[Heightmap] "Walking" on an heightmap

Started by
1 comment, last by Florian22222 12 years, 3 months ago
Hey there and welcome back :D

I´ve created an heightfield and i want my camera to move on it(I`m using DXUT for the Camera). All works fine but I`m experiencing "lags" while moving. Every time the 4 vertices(where I am interpolating lineary) changes, the camera changes the y-pos fast(about 2.0f).

This is my update method for the camera:

float y=g_pHeightfield->GetY(*g_pCamera->GetEyePt());
D3DXVECTOR3 vEye = *g_pCamera->GetEyePt();
D3DXVECTOR3 vLookAt = *g_pCamera->GetLookAtPt();
float deltaY = (y - vEye.y) + 1.0f;
vEye.y += deltaY;
vLookAt.y += deltaY;
g_pCamera->SetViewParams(&vEye,&vLookAt);


This is my GetY method in Heightfield

float GetY(D3DXVECTOR3 pos)
{
//transform
D3DXMATRIX inverseWorld;
D3DXMatrixInverse(&inverseWorld,NULL,&m_World);
D3DXVECTOR4 transformedVector = D3DXVECTOR4(pos.x,pos.y,pos.z,1.0f);
D3DXVec4Transform(&transformedVector,&transformedVector,&inverseWorld);
//check array out of bounds
if(transformedVector.x >= m_Width || transformedVector.x < 0 || transformedVector.z < 0 || transformedVector.z >= m_Height) return 0.0f; //if z or x = m_Height - 1 or m_Width -1; interpolate would read violent
D3DXVECTOR2 coord [] = {
D3DXVECTOR2((int)transformedVector.x,(int)transformedVector.z),
D3DXVECTOR2((int)transformedVector.x,(int)transformedVector.z+1),
D3DXVECTOR2((int)transformedVector.x+1,(int)transformedVector.z),
D3DXVECTOR2((int)transformedVector.x+1,(int)transformedVector.z+1),
};
float distance [] = { //distance²
sqrt(pow((transformedVector.x-coord[0].x),2) + pow((transformedVector.z-coord[0].y),2)),
sqrt(pow(1-(transformedVector.x-coord[0].x),2) + pow((transformedVector.z-coord[0].y),2)),
sqrt(pow((transformedVector.x-coord[0].x),2) + pow(1-(transformedVector.z-coord[0].y),2)),
sqrt(pow(1-(transformedVector.x-coord[0].x),2) + pow(1-(transformedVector.z-coord[0].y),2)),
};
float sumDistance = 0.0f;
for(int i=0; i < 4;i++)
{
sumDistance += distance;
}
float y = 0.0f;
for(int i = 0;i<4;i++)
{
if(distance == 0.0f)
{
return m_pHeights[(int)coord.y][(int)coord.x];
}
//use inverted distance(lower distance -> more effect)
y += (m_pHeights[(int)coord.y][(int)coord.x] * ( distance / sumDistance ));
}
return y;
};


in m_pHeights the heights are stored(I think it´s better to store them twice on cpu and gpu then locking it every time.

I hope you can help me, please :D
Advertisement
Two things:

1. When calculating distance, it seems you are using only coord[0]. You need to use the other ones as well! smile.png

sqrt(pow((transformedVector.x-coord[0].x),2) + pow((transformedVector.z-coord[0].y),2)),
sqrt(pow(1-(transformedVector.x-coord[1].x),2) + pow((transformedVector.z-coord[1].y),2)),
sqrt(pow((transformedVector.x-coord[2].x),2) + pow(1-(transformedVector.z-coord[2].y),2)),
sqrt(pow(1-(transformedVector.x-coord[3].x),2) + pow(1-(transformedVector.z-coord[3].y),2)),


2. When calculating the distance, you are subtracting ' transformedVector.z - coord[0].y ' This is correct since coord is a 2-dimensional vector and you stored the 'z' value in the 'y' slot, but it is confusing. It would be more readable to use a full 3-dimensional vector (even though you aren't using the 'y' member). With something like this, readability is everything.
thank you it´s working better now. but still not fluently. It´s like there are steps in the terrain, but there aren´t.

I´ve changed the code in update:

float y=g_pHeightfield->GetY(*g_pCamera->GetEyePt());
D3DXVECTOR3 vEye = *g_pCamera->GetEyePt();
D3DXVECTOR3 vLookAt = *g_pCamera->GetLookAtPt();


float deltaY = (y - vEye.y) +2.0f;

#define MAX_DELTA (1.0f*fElapsedTime)
if(abs(deltaY) > MAX_DELTA){
if(deltaY > 0) deltaY = MAX_DELTA;
else deltaY = -MAX_DELTA;
}

vEye.y += deltaY;
vLookAt.y += deltaY;
g_pCamera->SetViewParams(&vEye,&vLookAt);



Now it works fluently but i can walk through the terrain because then I can only go +1.0f/sec in y coord.
If i don´t change the code it doesnt run fluently at all.

This topic is closed to new replies.

Advertisement