Hard to tell without any code
There's a lot of code.
E_D3DVERTEX vert32[32][32];
E_D3DVERTEX vert16[16][16];//the templates
LPDIRECT3DINDEXBUFFER9 i_buff32=NULL,i_buff16=NULL;
const float InvPowerOf2[]={1,1.0f/2.0f,1.0f/4.0f,1.0f/8.0f,1.0f/16.0f,1.0f/32.0f,1.0f/64.0f,1.0f/128.0f,1.0f/256.0f,1.0f/512.0f,1.0f/1024.0f};
struct QTTOPLEVEL{
struct QTNODE{
QTNODE(){Child[0][0]=Child[0][1]=Child[1][0]=Child[1][1]=Parent=NULL;Level=-1;Type=-1;pVertexObject=NULL;}
QTNODE(QTNODE* P,int L){Child[0][0]=Child[0][1]=Child[1][0]=Child[1][1]=NULL; Parent=P;Level=L;Type=-1;pVertexObject=NULL;}
~QTNODE(){
if (pVertexObject!=NULL) pVertexObject->Release();
}
QTNODE* Parent;
QTNODE* Child[2][2];
LPDIRECT3DVERTEXBUFFER9 pVertexObject ;//this is the final product mesh after all the calcs are done...
//no need to have an index buffer because it is a generic IB that is pre-calculated and referenced by Type
int Type;//this refers to a generic flat mesh and index.
E_D3DVERTEX vert[32][32];//may make this a **pointer ???
float locX,locZ;//location that this node is on the "plane"
float sizeSquared;//used when checking the distance from "detail center".... uses THE SQUARE so calcs are faster
int Level;//how far from the top level
void UpdateNode(QTTOPLEVEL *Top,GAMEENGINE *GE);//test for radius (of this level) going through this node
void CreateLevel(QTTOPLEVEL *Top,GAMEENGINE *GE);//QTNODE *Top refers to the top most (where float detailRadius[6]; ,float plocX,plocZ; and int MaxLevel; are located
};
QTNODE TopLevelNode[2][2];
int Planet;
float planetSizeX,planetSizeY;//this is the texture and heightmap size
bool Detailed;//this is true if it is one of the 3 sides of the cube that is being detailed
int MaxLevel;//the detail level
float plocX,plocZ; //the point of detail. Where the "detail center" is on the plane.
float detailRadius[6];//these will determine how far each node needs to go to get correct detail..... max of 6 levels of detail...?
//in order of largest radius to smallest(nearest and highest detail).... SQUARE VALUE?
D3DXMATRIX faceOrientation;//********** the templates are oriented as y==1 is up. this matrix is used to convert that to the cube's face orientation that this QTTOPLEVEL represents
void UpdateQT(GAMEENGINE *GE);
};
/*
cube point to sphere point:
sx = x * sqrtf(1.0f - y * y * 0.5f - z * z * 0.5f + y * y * z * z / 3.0f);
sy = y * sqrtf(1.0f - z * z * 0.5f - x * x * 0.5f + z * z * x * x / 3.0f);
sz = z * sqrtf(1.0f - x * x * 0.5f - y * y * 0.5f + x * x * y * y / 3.0f);
*/
//point on sphere to point on cube:
struct dVect3{
double x,y,z;
};
void cubizePoint(D3DXVECTOR3& p){
dVect3 position;
position.x=p.x;
position.y=p.y;
position.z=p.z;
double x,y,z;
x = position.x;
y = position.y;
z = position.z;
double fx, fy, fz;
fx = abs(x);
fy = abs(y);
fz = abs(z);
const double inverseSqrt2 = 0.70710676908493042;
if (fy >= fx && fy >= fz) {
double a2 = x * x * 2.0;
double b2 = z * z * 2.0;
double inner = -a2 + b2 -3;
double innersqrt = -sqrt((inner * inner) - 12.0 * a2);
if(x == 0.0 || x == -0.0) {
position.x = 0.0;
}
else {
position.x = sqrt(innersqrt + a2 - b2 + 3.0) * inverseSqrt2;
}
if(z == 0.0 || z == -0.0) {
position.z = 0.0;
}
else {
position.z = sqrt(innersqrt - a2 + b2 + 3.0) * inverseSqrt2;
}
if(position.x > 1.0) position.x = 1.0;
if(position.z > 1.0) position.z = 1.0;
if(x < 0) position.x = -position.x;
if(z < 0) position.z = -position.z;
if (y > 0) {
// top face
position.y = 1.0;
}
else {
// bottom face
position.y = -1.0;
}
}
else if (fx >= fy && fx >= fz) {
double a2 = y * y * 2.0;
double b2 = z * z * 2.0;
double inner = -a2 + b2 -3;
double innersqrt = -sqrt((inner * inner) - 12.0 * a2);
if(y == 0.0 || y == -0.0) {
position.y = 0.0;
}
else {
position.y = sqrt(innersqrt + a2 - b2 + 3.0) * inverseSqrt2;
}
if(z == 0.0 || z == -0.0) {
position.z = 0.0;
}
else {
position.z = sqrt(innersqrt - a2 + b2 + 3.0) * inverseSqrt2;
}
if(position.y > 1.0) position.y = 1.0;
if(position.z > 1.0) position.z = 1.0;
if(y < 0) position.y = -position.y;
if(z < 0) position.z = -position.z;
if (x > 0) {
// right face
position.x = 1.0;
}
else {
// left face
position.x = -1.0;
}
}
else {
double a2 = x * x * 2.0;
double b2 = y * y * 2.0;
double inner = -a2 + b2 -3;
double innersqrt = -sqrt((inner * inner) - 12.0 * a2);
if(x == 0.0 || x == -0.0) {
position.x = 0.0;
}
else {
position.x = sqrt(innersqrt + a2 - b2 + 3.0) * inverseSqrt2;
}
if(y == 0.0 || y == -0.0) {
position.y = 0.0;
}
else {
position.y = sqrt(innersqrt - a2 + b2 + 3.0) * inverseSqrt2;
}
if(position.x > 1.0) position.x = 1.0;
if(position.y > 1.0) position.y = 1.0;
if(x < 0) position.x = -position.x;
if(y < 0) position.y = -position.y;
if (z > 0) {
// front face
position.z = 1.0;
}
else {
// back face
position.z = -1.0;
}
}
p=D3DXVECTOR3(float(position.x),float(position.y),float(position.z));
}
void PLANETTERRAIN::Init(GAMEENGINE *GE,int Planet){
//delete any old stuff
Delete();
//determine parameters for the terrain from the planet
for (int cf=0;cf<6;cf++){
CubeFaces[cf].Detailed=true;
CubeFaces[cf].Planet=Planet;
CubeFaces[cf].MaxLevel=5;//**************** will be higher when I am sure it works right
CubeFaces[cf].detailRadius[0]=1024;//ALWAYS ???
// CubeFaces[cf].detailRadius[1]=SolarSystem.Planet[Planet].Size;//************ this is where I will need to decide what the radius size is for each detail level
CubeFaces[cf].detailRadius[1]=CubeFaces[cf].detailRadius[0]/2.0f;//************ this is where I will need to decide what the radius size is for each detail level
CubeFaces[cf].detailRadius[2]=CubeFaces[cf].detailRadius[1]/2.0f;
CubeFaces[cf].detailRadius[3]=CubeFaces[cf].detailRadius[2]/2.0f;
CubeFaces[cf].detailRadius[4]=CubeFaces[cf].detailRadius[3]/2.0f;
CubeFaces[cf].detailRadius[5]=CubeFaces[cf].detailRadius[4]/2.0f;
CubeFaces[cf].TopLevelNode[0][0].locX=-500;
CubeFaces[cf].TopLevelNode[0][0].locZ=-500;
CubeFaces[cf].TopLevelNode[1][0].locX=0;
CubeFaces[cf].TopLevelNode[1][0].locZ=-500;
CubeFaces[cf].TopLevelNode[0][1].locX=-500;
CubeFaces[cf].TopLevelNode[0][1].locZ=0;
CubeFaces[cf].TopLevelNode[1][1].locX=0;
CubeFaces[cf].TopLevelNode[1][1].locZ=0;
CubeFaces[cf].TopLevelNode[0][0].sizeSquared=500000.0f;//this is 500*500+500*500
CubeFaces[cf].TopLevelNode[1][0].sizeSquared=500000.0f;
CubeFaces[cf].TopLevelNode[0][1].sizeSquared=500000.0f;
CubeFaces[cf].TopLevelNode[1][1].sizeSquared=500000.0f;
CubeFaces[cf].planetSizeX=720;
CubeFaces[cf].planetSizeY=360;
if (SolarSystem.Planet[Planet].Size<2000.0f){
CubeFaces[cf].planetSizeX/=2;
CubeFaces[cf].planetSizeY/=2;
}
}
}
void PLANETTERRAIN::Delete(){
for (int cf=0;cf<6;cf++){
for (int tlnx=0;tlnx<2;tlnx++){
for (int tlnz=0;tlnz<2;tlnz++){
if (CubeFaces[cf].TopLevelNode[tlnx][tlnz].Child[0][0]!=NULL){
CubeFaces[cf].TopLevelNode[tlnx][tlnz].Child[0][0]->~QTNODE();
CubeFaces[cf].TopLevelNode[tlnx][tlnz].Child[1][0]->~QTNODE();
CubeFaces[cf].TopLevelNode[tlnx][tlnz].Child[0][1]->~QTNODE();
CubeFaces[cf].TopLevelNode[tlnx][tlnz].Child[1][1]->~QTNODE();
}
if (CubeFaces[cf].TopLevelNode[tlnx][tlnz].pVertexObject!=NULL) CubeFaces[cf].TopLevelNode[tlnx][tlnz].pVertexObject->Release();
CubeFaces[cf].TopLevelNode[tlnx][tlnz].pVertexObject=NULL;
}
}
}
}
void PLANETTERRAIN::Update(GAMEENGINE *GE){
GE->d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
//update the center position
// SphereDetailCenter;
//testing
D3DXVECTOR3 point;
D3DXVECTOR2 facePoint[6];//facePoint[] uses x,y values only
point=GE->MyCamera.m_viewDir*-1.0f;
//D3DXMATRIX tmp;
//D3DXMatrixRotationY(&tmp,-D3DX_PI/5.0f);
//D3DXVec3TransformCoord(&point,&point,&tmp);
cubizePoint(point);
point*=500.0f;
if (point.x==500.0f){//cf==3 E
for (int i=0;i<6;i++) facePoint[i]=D3DXVECTOR2(1000000,1000000);
facePoint[3].x=point.z;
facePoint[3].y=point.y;
if (point.z>0.0f){
facePoint[5].x=point.z-1000.0f;
facePoint[5].y=point.y;
}
else{
facePoint[4].x=point.z+1000.0f;
facePoint[4].y=point.y;
}
if (point.y>0.0f){
facePoint[0].y=point.z;
facePoint[0].x=-(point.y-1000.0f);
}
else{
facePoint[1].y=-point.z;
facePoint[1].x=point.y+1000.0f;
}
}
if (point.x==-500.0f){//cf==2 W
for (int i=0;i<6;i++) facePoint[i]=D3DXVECTOR2(1000000,1000000);
facePoint[2].x=-point.z;
facePoint[2].y=point.y;
if (point.z>0.0f){
facePoint[5].x=-(point.z-1000.0f);
facePoint[5].y=point.y;
}
else{
facePoint[4].x=-(point.z+1000.0f);
facePoint[4].y=point.y;
}
if (point.y>0.0f){
facePoint[0].y=point.z;
facePoint[0].x=point.y-1000.0f;
}
else{
facePoint[1].y=-point.z;
facePoint[1].x=-(point.y+1000.0f);
}
}
if (point.z==500.0f){//cf==5
for (int i=0;i<6;i++) facePoint[i]=D3DXVECTOR2(1000000,1000000);
facePoint[5].x=-point.x;
facePoint[5].y=point.y;
if (point.x<0.0f){
facePoint[2].x=-point.x-1000.0f;
facePoint[2].y=point.y;
}
else{
facePoint[3].x=1000.0f-point.x;
facePoint[3].y=point.y;
}
if (point.y>0.0f){
facePoint[0].x=point.x;
facePoint[0].y=1000.0f-point.y;
}
else{
facePoint[1].x=point.x;
facePoint[1].y=-(point.y+1000.0f);
}
}
if (point.z==-500.0f){//cf==4
for (int i=0;i<6;i++) facePoint[i]=D3DXVECTOR2(1000000,1000000);
facePoint[4].x=point.x;
facePoint[4].y=point.y;
if (point.x>0.0f){
facePoint[3].x=point.x-1000.0f;
facePoint[3].y=point.y;
}
else{
facePoint[2].x=point.x+1000.0f;
facePoint[2].y=point.y;
}
if (point.y>0.0f){
facePoint[0].x=point.x;
facePoint[0].y=point.y-1000.0f;
}
else{
facePoint[1].x=point.x;
facePoint[1].y=point.y+1000.0f;
}
}
if (point.y==500.0f){//cf==0
for (int i=0;i<6;i++) facePoint[i]=D3DXVECTOR2(1000000,1000000);
facePoint[0].x=point.x;
facePoint[0].y=point.z;
if (point.x<0.0f){
facePoint[2].y=point.x+1000.0f;
facePoint[2].x=-point.z;
}
else{
facePoint[3].y=1000.0f-point.x;
facePoint[3].x=point.z;
}
if (point.z>0.0f){
facePoint[5].x=-point.x;
facePoint[5].y=1000.0f-point.z;
}
else{
facePoint[4].x=point.x;
facePoint[4].y=point.z+1000.0f;
}
}
if (point.y==-500.0f){//cf==1
for (int i=0;i<6;i++) facePoint[i]=D3DXVECTOR2(1000000,1000000);
facePoint[1].x=point.x;
facePoint[1].y=-point.z;
if (point.x<0.0f){
facePoint[2].y=-(point.x+1000.0f);
facePoint[2].x=-point.z;
}
else{
facePoint[3].y=point.x-1000.0f;
facePoint[3].x=point.z;
}
if (point.z>0.0f){
facePoint[5].x=-point.x;
facePoint[5].y=point.z-1000.0f;
}
else{
facePoint[4].x=point.x;
facePoint[4].y=-(point.z+1000.0f);
}
}
for (int cf=4;cf<5;cf++){
CubeFaces[cf].plocX=facePoint[cf].x;
CubeFaces[cf].plocZ=facePoint[cf].y;
CubeFaces[cf].UpdateQT(GE);
}
GE->d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
}
void GenerateTerrainTemplates(GAMEENGINE *GE){
short index32[5766];//index buffres for the templates
short index16[1350];//total number of faces*3
//do the 32x32
for (int z=0;z<32;z++){
for (int x=0;x<32;x++){
vert32[x][z].v=D3DXVECTOR3(float(31-x)/31.0f,0,float(z)/31.0f);
vert32[x][z].tu=float(x)/32.0f;
vert32[x][z].tv=float(z)/32.0f;
//the normals will have to be calculated when it is in place on the sphere
}
}
int pos=0;
for (int ty=0;ty<31;ty++){
for (int tx=0;tx<31;tx++){
index32[pos]=short((ty*32)+tx+1);
index32[pos+2]=short((ty*32)+tx);
index32[pos+1]=short(((ty+1)*32)+tx);
pos+=3;
index32[pos]=short((ty*32)+tx+1);
index32[pos+2]=short(((ty+1)*32)+tx);
index32[pos+1]=short(((ty+1)*32)+tx+1);
pos+=3;
}
}
GE->d3ddev->CreateIndexBuffer(5766 *sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buff32,
NULL);
void *pVoid;
i_buff32->Lock(0, 0, (void**)&pVoid, 0);
short *pint=(short*)pVoid;
for (UINT i=0;i<5766;i++){
pint[i]=index32[i];
}
i_buff32->Unlock();
//do the 16x16
for (int z=0;z<16;z++){
for (int x=0;x<16;x++){
vert16[x][z].v=D3DXVECTOR3(float(15-x)/15.0f,0,float(z)/15.0f);
vert16[x][z].tu=float(x)/16.0f;
vert16[x][z].tv=float(z)/16.0f;
//the normals will have to be calculated when it is in place on the sphere
}
}
pos=0;
for (int ty=0;ty<15;ty++){
for (int tx=0;tx<15;tx++){
index16[pos]=short((ty*16)+tx+1);
index16[pos+2]=short((ty*16)+tx);
index16[pos+1]=short(((ty+1)*16)+tx);
pos+=3;
index16[pos]=short((ty*16)+tx+1);
index16[pos+2]=short(((ty+1)*16)+tx);
index16[pos+1]=short(((ty+1)*16)+tx+1);
pos+=3;
}
}
GE->d3ddev->CreateIndexBuffer(1350 *sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buff16,
NULL);
i_buff16->Lock(0, 0, (void**)&pVoid, 0);
pint=(short*)pVoid;
for (UINT i=0;i<1350;i++){
pint[i]=index16[i];
}
i_buff16->Unlock();
}
void QTTOPLEVEL::UpdateQT(GAMEENGINE *GE){
TopLevelNode[0][0].UpdateNode(this,GE);
TopLevelNode[0][1].UpdateNode(this,GE);
TopLevelNode[1][0].UpdateNode(this,GE);
TopLevelNode[1][1].UpdateNode(this,GE);
}
void QTTOPLEVEL::QTNODE::UpdateNode(QTTOPLEVEL *Top,GAMEENGINE *GE){
float shift=500.0f*InvPowerOf2[Level+2];
float Dist=((locX-Top->plocX+shift)*(locX-Top->plocX+shift))+((locZ-Top->plocZ+shift)*(locZ-Top->plocZ+shift));
Dist-=sizeSquared;
if (Dist>Top->detailRadius[Level+1]){
if (Child[0][0]!=NULL){
//destroy only if no children and is not the top level
if (Child[0][0]->Child[0][0]==NULL){
//destroy the childs
if (Child[0][0]->pVertexObject!=NULL) Child[0][0]->pVertexObject->Release();
delete Child[0][0];
Child[0][0]=NULL;
if (Child[1][0]->pVertexObject!=NULL) Child[1][0]->pVertexObject->Release();
delete Child[1][0];
Child[1][0]=NULL;
if (Child[0][1]->pVertexObject!=NULL) Child[0][1]->pVertexObject->Release();
delete Child[0][1];
Child[0][1]=NULL;
if (Child[1][1]->pVertexObject!=NULL) Child[1][1]->pVertexObject->Release();
delete Child[1][1];
Child[1][1]=NULL;
}
}
}
//determine if current level is generated
//determine the level (16 or 32)
float D=((locX-Top->plocX+shift)*(locX-Top->plocX+shift))+((locZ-Top->plocZ+shift)*(locZ-Top->plocZ+shift));
D-=sizeSquared;
if (D<Top->detailRadius[Level+1]){//size 32
if (Type!=0){
if (pVertexObject!=NULL) pVertexObject->Release();
GE->d3ddev->CreateVertexBuffer(32*32 *sizeof(E_D3DVERTEX), 0,
E_D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pVertexObject, NULL);
float size=500.0f*InvPowerOf2[Level+1];
//copy from the template
for (int z=0;z<32;z++){
for (int x=0;x<32;x++){
vert[x][z]=vert32[x][z];
vert[x][z].v*=size;
vert[x][z].v.x+=locX;
vert[x][z].v.z+=locZ;
vert[x][z].v.x*=0.002f;
vert[x][z].v.z*=0.002f;
vert[x][z].v.y=1.0f;
D3DXVec3TransformCoord(&vert[x][z].v,&vert[x][z].v,&Top->faceOrientation);
//******** spherify the coordinates
float sx = vert[x][z].v.x * sqrtf(1.0f - vert[x][z].v.y * vert[x][z].v.y * 0.5f - vert[x][z].v.z * vert[x][z].v.z * 0.5f + vert[x][z].v.y * vert[x][z].v.y * vert[x][z].v.z * vert[x][z].v.z / 3.0f);
float sy = vert[x][z].v.y * sqrtf(1.0f - vert[x][z].v.z * vert[x][z].v.z * 0.5f - vert[x][z].v.x * vert[x][z].v.x * 0.5f + vert[x][z].v.z * vert[x][z].v.z * vert[x][z].v.x * vert[x][z].v.x / 3.0f);
float sz = vert[x][z].v.z * sqrtf(1.0f - vert[x][z].v.x * vert[x][z].v.x * 0.5f - vert[x][z].v.y * vert[x][z].v.y * 0.5f + vert[x][z].v.x * vert[x][z].v.x * vert[x][z].v.y * vert[x][z].v.y / 3.0f);
vert[x][z].v=D3DXVECTOR3(sx,sy,sz);//this is already normalized
vert[x][z].n=vert[x][z].v;//use this for normal unless something else is needed
//get the lat/lon for each point and convert it into texture coordinates
float lat=atan2(vert[x][z].v.x,vert[x][z].v.z)+D3DX_PI;//********* this is wrong, but it allows me to see the problem without having to move
// float lat=atan2(vert[x][z].v.z,vert[x][z].v.x)+D3DX_PI;
lat/=D3DX_PI*2.0f;
float lon=asin(-vert[x][z].v.y)+D3DX_PI/2.0f;
lon/=D3DX_PI;
if ((x==0)&&(lat>0.999f)) lat=0.0f;
vert[x][z].tu=1.25f-lat;
vert[x][z].tv=lon;
lat=1.0f-lat;
if (lat>=1.0f) lat=0.0f;
lat+=0.25f;
if (lat>=1.0f) lat-=1.0f;
float elev=SolarSystem.Planet[Top->Planet].PlanetTopography[int(Top->planetSizeX*lat)][int(Top->planetSizeY*lon)]/500.0f;
vert[x][z].v*=1000.0f;//+elev;
//*********************** HERE IS WHERE I NEED TO DO THE TEXTURE COORDINATES (IF AT TOP LEVEL ONLY?)
//************ ALSO NEED TO GENERATE TEXTURES FOR LOWER LEVEL STUFF????
//********** MAY USE THE PLANET'S TEXTURE ONLY.... NOT GENERATING TEXTURES FOR THIS TERRAIN SKIRT?
}
}
void *pVoid;
pVertexObject->Lock(0, 32*32*sizeof(E_D3DVERTEX), &pVoid, D3DLOCK_DISCARD);
E_D3DVERTEX *vertb=(E_D3DVERTEX*) pVoid;
int c=0;
for (int z=0;z<32;z++){
for (int x=0;x<32;x++){
vertb[c]=vert[x][z];
c++;
}
}
Type=0;
pVertexObject->Unlock();
}
}
else{//size 16
if (Type!=1){
if (pVertexObject!=NULL) pVertexObject->Release();
GE->d3ddev->CreateVertexBuffer(16*16 *sizeof(E_D3DVERTEX), 0,
E_D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pVertexObject, NULL);
void *pVoid;
pVertexObject->Lock(0, 16*16*sizeof(E_D3DVERTEX), &pVoid, D3DLOCK_DISCARD);
E_D3DVERTEX *vertb=(E_D3DVERTEX*) pVoid;
int c=0;
float size=500.0f*InvPowerOf2[Level+1];
//copy from the template
for (int z=0;z<32;z+=2){
for (int x=0;x<32;x+=2){
vert[x][z]=vert16[x/2][z/2];
vert[x][z].v*=size;
vert[x][z].v.x+=locX;
vert[x][z].v.z+=locZ;
vert[x][z].v.x*=0.002f;
vert[x][z].v.z*=0.002f;
vert[x][z].v.y=1.0f;
D3DXVec3TransformCoord(&vert[x][z].v,&vert[x][z].v,&Top->faceOrientation);
//******** spherify the coordinates
float sx = vert[x][z].v.x * sqrtf(1.0f - vert[x][z].v.y * vert[x][z].v.y * 0.5f - vert[x][z].v.z * vert[x][z].v.z * 0.5f + vert[x][z].v.y * vert[x][z].v.y * vert[x][z].v.z * vert[x][z].v.z / 3.0f);
float sy = vert[x][z].v.y * sqrtf(1.0f - vert[x][z].v.z * vert[x][z].v.z * 0.5f - vert[x][z].v.x * vert[x][z].v.x * 0.5f + vert[x][z].v.z * vert[x][z].v.z * vert[x][z].v.x * vert[x][z].v.x / 3.0f);
float sz = vert[x][z].v.z * sqrtf(1.0f - vert[x][z].v.x * vert[x][z].v.x * 0.5f - vert[x][z].v.y * vert[x][z].v.y * 0.5f + vert[x][z].v.x * vert[x][z].v.x * vert[x][z].v.y * vert[x][z].v.y / 3.0f);
vert[x][z].v=D3DXVECTOR3(sx,sy,sz);//this is already normalized
vert[x][z].n=vert[x][z].v;//use this for normal unless something else is needed
//get the lat/lon for each point and convert it into texture coordinates
float lat=atan2(vert[x][z].v.x,vert[x][z].v.z)+D3DX_PI;//********* this is wrong, but it allows me to see the problem without having to move
// float lat=atan2(vert[x][z].v.z,vert[x][z].v.x)+D3DX_PI;
lat/=D3DX_PI*2.0f;
float lon=asin(-vert[x][z].v.y)+D3DX_PI/2.0f;
lon/=D3DX_PI;
if ((x==0)&&(lat>0.999f)) lat=0.0f;
vert[x][z].tu=1.25f-lat;
vert[x][z].tv=lon;
lat=1.0f-lat;
if (lat>=1.0f) lat=0.0f;
lat+=0.25f;
if (lat>=1.0f) lat-=1.0f;
float elev=SolarSystem.Planet[Top->Planet].PlanetTopography[int(Top->planetSizeX*lat)][int(Top->planetSizeY*lon)]/500.0f;
vert[x][z].v*=1000.0f;//+elev;
//*********************** HERE IS WHERE I NEED TO DO THE TEXTURE COORDINATES (IF AT TOP LEVEL ONLY?)
//************ ALSO NEED TO GENERATE TEXTURES FOR LOWER LEVEL STUFF????
//********** MAY USE THE PLANET'S TEXTURE ONLY.... NOT GENERATING TEXTURES FOR THIS TERRAIN SKIRT?
vertb[c]=vert[x][z];
c++;
}
}
Type=1;
pVertexObject->Unlock();
}
}
//update the childs
if (Child[0][0]!=NULL){//if first child is good, then all are there
Child[0][0]->UpdateNode(Top,GE);
Child[0][1]->UpdateNode(Top,GE);
Child[1][0]->UpdateNode(Top,GE);
Child[1][1]->UpdateNode(Top,GE);
}
else{//determine if children are needed
//*********************** render here????????????????????
//getting here indicates that there are no childs (or they were just created). So this is the most detailed level
D3DXMATRIX wm;
D3DXMatrixIdentity(&wm);
D3DXVECTOR3 lv(0,0,1000);//put it somewhere in front of the camera
lv=GE->MyCamera.m_viewDir*2000.0f;
wm(3,0)=lv.x;
wm(3,1)=lv.y;
wm(3,2)=lv.z;
GE->d3ddev->SetTransform(D3DTS_WORLD,&wm);
GE->d3ddev->SetMaterial(&GlowMatl);//DefaultMatl
GE->d3ddev->SetTexture(0,TextureList[SolarSystem.Planet[Top->Planet].BodyTex].Texture);
GE->d3ddev->SetFVF(E_D3DFVF_CUSTOMVERTEX);
if (Type==0){
GE->d3ddev->SetIndices(i_buff32);
GE->d3ddev->SetStreamSource(0, pVertexObject, 0, sizeof(E_D3DVERTEX));
GE->d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 1024, 0, 1922);
}
if (Type==1){
GE->d3ddev->SetIndices(i_buff16);
GE->d3ddev->SetStreamSource(0, pVertexObject, 0, sizeof(E_D3DVERTEX));
GE->d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 256, 0, 450);
}
if (Top->Detailed){
if (Level<Top->MaxLevel){
//get the distance of the center to the point of intersection
float D=((locX-Top->plocX+shift)*(locX-Top->plocX+shift))+((locZ-Top->plocZ+shift)*(locZ-Top->plocZ+shift));
D-=sizeSquared;
if (D<Top->detailRadius[Level+1]){
CreateLevel(Top,GE);
}
}
}
}
}
void QTTOPLEVEL::QTNODE::CreateLevel(QTTOPLEVEL *Top,GAMEENGINE *GE){
float size=500.0f*InvPowerOf2[Level+2];//yea, +2 is right
float SS=size*size*2.0f;
Child[0][0]=new QTTOPLEVEL::QTNODE(this,Level+1);
Child[0][0]->locX=locX;
Child[0][0]->locZ=locZ;
//do the size.....
Child[0][0]->sizeSquared=SS;
Child[0][1]=new QTTOPLEVEL::QTNODE(this,Level+1);
Child[0][1]->locX=locX;
Child[0][1]->locZ=locZ+size;
//do the size.....
Child[0][1]->sizeSquared=SS;
Child[1][0]=new QTTOPLEVEL::QTNODE(this,Level+1);
Child[1][0]->locX=locX+size;
Child[1][0]->locZ=locZ;
//do the size.....
Child[1][0]->sizeSquared=SS;
Child[1][1]=new QTTOPLEVEL::QTNODE(this,Level+1);
Child[1][1]->locX=locX+size;
Child[1][1]->locZ=locZ+size;
//do the size.....
Child[1][1]->sizeSquared=SS;
}
So far, EVERYTHING is being rendered. As I stated in the OP, I am trying to implement 6 quad-trees that form a cube and then (when generating the cube faces) converted into a sphere. So far it is working out. I just can't figure out how to tell what each squares neighbors are. If I knew how to get it, I think I could fix the "seams not lining up" problem (problem 2).