|
|
以下是以原点(0 , 0, 0)为球心生成半球的
void CDomeSky::GenerateDome(float radius, float dtheta, float dphi, float hTile, float vTile)
{
int theta, phi;
// 如果顶点序列存在,则清空顶点序列
if (Vertices)
{
delete Vertices;
Vertices = NULL;
NumVertices = 0;
}
// 初始化顶点序列
NumVertices = (int)((360/dtheta)*(90/dphi)*4);
Vertices = new VERTEX[NumVertices];
ZeroMemory(Vertices, sizeof(VERTEX)*NumVertices);
// 用来计算 UV 坐标
float vx, vy, vz, mag;
// 生成拱形天空dome
int n = 0;
for (phi=0; phi <= 90 - dphi; phi += (int)dphi)
{
for (theta=0; theta <= 360 - dtheta; theta += (int)dtheta)
{
// 计算顶点的 phi, theta
Vertices[n].x = radius * sinf(phi*DTOR) * cosf(DTOR*theta);
Vertices[n].y = radius * sinf(phi*DTOR) * sinf(DTOR*theta);
Vertices[n].z = radius * cosf(phi*DTOR);
// 计算从原点到该顶点的矢量
vx = Vertices[n].x;
vy = Vertices[n].y;
vz = Vertices[n].z;
// 矢量正交化
mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
// 计算球形纹理坐标
Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;
n++;
// 计算位置在phi+dphi, theta处的顶点
Vertices[n].x = radius * sinf((phi+dphi)*DTOR) * cosf(theta*DTOR);
Vertices[n].y = radius * sinf((phi+dphi)*DTOR) * sinf(theta*DTOR);
Vertices[n].z = radius * cosf((phi+dphi)*DTOR);
// 计算纹理坐标
vx = Vertices[n].x;
vy = Vertices[n].y;
vz = Vertices[n].z;
mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;
n++;
// 计算位于phi, theta+dtheta处的顶点坐标
Vertices[n].x = radius * sinf(DTOR*phi) * cosf(DTOR*(theta+dtheta));
Vertices[n].y = radius * sinf(DTOR*phi) * sinf(DTOR*(theta+dtheta));
Vertices[n].z = radius * cosf(DTOR*phi);
// 计算纹理坐标
vx = Vertices[n].x;
vy = Vertices[n].y;
vz = Vertices[n].z;
mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;
n++;
if (phi > -90 && phi < 90)
{
// 计算位于 phi+dphi, theta+dtheta处的顶点坐标
Vertices[n].x = radius * sinf((phi+dphi)*DTOR) * cosf(DTOR*(theta+dtheta));
Vertices[n].y = radius * sinf((phi+dphi)*DTOR) * sinf(DTOR*(theta+dtheta));
Vertices[n].z = radius * cosf((phi+dphi)*DTOR);
// 计算纹理坐标
vx = Vertices[n].x;
vy = Vertices[n].y;
vz = Vertices[n].z;
mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;
n++;
}
}
}
// 修改纹理坐标
for (int i=0; i < NumVertices-3; i++)
{
if (Vertices.u - Vertices[i+1].u > 0.9f)
Vertices[i+1].u += 1.0f;
if (Vertices[i+1].u - Vertices.u > 0.9f)
Vertices.u += 1.0f;
if (Vertices.u - Vertices[i+2].u > 0.9f)
Vertices[i+2].u += 1.0f;
if (Vertices[i+2].u - Vertices.u > 0.9f)
Vertices.u += 1.0f;
if (Vertices[i+1].u - Vertices[i+2].u > 0.9f)
Vertices[i+2].u += 1.0f;
if (Vertices[i+2].u - Vertices[i+1].u > 0.9f)
Vertices[i+1].u += 1.0f;
if (Vertices.v - Vertices[i+1].v > 0.8f)
Vertices[i+1].v += 1.0f;
if (Vertices[i+1].v - Vertices.v > 0.8f)
Vertices.v += 1.0f;
if (Vertices.v - Vertices[i+2].v > 0.8f)
Vertices[i+2].v += 1.0f;
if (Vertices[i+2].v - Vertices.v > 0.8f)
Vertices.v += 1.0f;
if (Vertices[i+1].v - Vertices[i+2].v > 0.8f)
Vertices[i+2].v += 1.0f;
if (Vertices[i+2].v - Vertices[i+1].v > 0.8f)
Vertices[i+1].v += 1.0f;
}
}
请问如果我要以比如(250, 0, 250)为球心生成半球改动,
我试了好多都没有成功 |
|