Setting a path for objects

Started by
7 comments, last by Anddos 9 years, 8 months ago

I am following setting paths for 3D Objects in my book, what i want todo is add more paths instead of it reseting back to the right hand side of the screen, what do i need to change so the 3D Object goes along all the set paths,thanks for reading

void init_graphics(void)
{
    Path[0].x = -2.5f; Path[0].y = 1.0f; Path[0].z = 0.0f;
Path[1].x = 2.5f; Path[1].y = 1.0f; Path[1].z = 0.0f;
Path[2].x = 2.5f; Path[2].y = 1.0f; Path[2].z = 0.0f;
Path[3].x = -2.5f; Path[3].y = 1.0f; Path[3].z = 0.0f;
 
StartTime = (float)timeGetTime();
 
// create the vertices using the CUSTOMVERTEX struct
    CUSTOMVERTEX vertices[] = 
    {
        { 1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
        { 0.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
        { -1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
    };
 
    // create a vertex buffer interface called v_buffer
    d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
                               0,
                               CUSTOMFVF,
                               D3DPOOL_MANAGED,
                               &v_buffer,
                               NULL);
 
    VOID* pVoid;    // a void pointer
 
    // lock v_buffer and load the vertices into it
    v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, vertices, sizeof(vertices));
    v_buffer->Unlock();
}
 

void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
 
    d3ddev->BeginScene();
 
    // select which vertex format we are using
    d3ddev->SetFVF(CUSTOMFVF);
 
    // SET UP THE PIPELINE
 
    D3DXMATRIX matRotateY;    // a matrix to store the rotation information
 
    static float index = 0.0f; index+=0.05f;    // an ever-increasing float value
 
    // build a matrix to rotate the model based on the increasing float value
    D3DXMatrixRotationY(&matRotateY, index);
 
    // tell Direct3D about our matrix
    d3ddev->SetTransform(D3DTS_WORLD, &matRotateY);
 
    D3DXMATRIX matView;    // the view transform matrix
 
    D3DXMatrixLookAtLH(&matView,
                       &D3DXVECTOR3 (0.0f, 0.0f, 5.0f),    // the camera position
                       &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),    // the look-at position
                       &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
 
    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView
 
    D3DXMATRIX matProjection;     // the projection transform matrix
 
    D3DXMatrixPerspectiveFovLH(&matProjection,
                               D3DXToRadian(45),    // the horizontal field of view
                               (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
                               0.1f,    // the near view-plane
                               100.0f);    // the far view-plane
 
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection
 
 
float Scalar = (float)timeGetTime();
Scalar = (Scalar -StartTime) * 0.0003f;
 
if(CurrentPath == 1)
{
stVector diff;
diff.x = Path[1].x - Path[0].x;
diff.y = Path[1].y - Path[0].y;
diff.z = Path[1].z - Path[0].z;
 
float len = (float)sqrt((diff.x * diff.x +
                   diff.y * diff.y +
diff.z * diff.z));
Scalar = Scalar / len;
objPos.x = (Path[1].x - Path[0].x) * Scalar + Path[0].x;
objPos.y = (Path[1].y - Path[0].y) * Scalar + Path[0].y;
objPos.z = (Path[1].z - Path[0].z) * Scalar + Path[0].z;
}
else
{
stVector diff;
diff.x = Path[3].x - Path[2].x;
diff.x = Path[3].y - Path[2].y;
diff.x = Path[3].z - Path[2].z;
 
float len = (float)sqrt((diff.x * diff.x +
                    diff.y * diff.y +
diff.z * diff.z));
 
Scalar = Scalar / len;
objPos.x = (Path[3].x - Path[2].x) * Scalar + Path[2].x;
objPos.y = (Path[3].y - Path[2].y) * Scalar + Path[2].y;
objPos.z = (Path[3].z - Path[2].z) * Scalar + Path[2].z;
}
 
if(Scalar >= 1.0f)
{
StartTime = (float)timeGetTime();
 
CurrentPath++;
 
if(CurrentPath > 2) CurrentPath = 1;
 
}
 
D3DXMATRIX mat;
//D3DXMatrixIdentity(&mat);
D3DXMatrixTranslation(&mat,objPos.x,objPos.y,objPos.z);
d3ddev->SetTransform(D3DTS_WORLD,&mat);
 
    // select the vertex buffer to display
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
 
    // copy the vertex buffer to the back buffer
    d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
 
    d3ddev->EndScene();
 
    d3ddev->Present(NULL, NULL, NULL, NULL);
}

 
:)
Advertisement

I'm not sure but i think it goes from Path[0] to Path[1] then Path[2] to Path[3]. It would be easier if it went from Path[0] to Path[1] to Path[2] to Path[3]. Then it would be a simple case of iterating over them. Try maybe this instead of your if-else:


// Needs to know about diff, Scalar and obPos. I assume they are global
void SetPath(UINT uiStart, UINT uiEnd)
{
	diff.x = Path[uiEnd].x - Path[uiStart].x;
	diff.y = Path[uiEnd].y - Path[uiStart].y;
	diff.z = Path[uiEnd].z - Path[uiStart].z;
 
	float len = (float)sqrt((diff.x * diff.x +
					   diff.y * diff.y +
	diff.z * diff.z));
	Scalar = Scalar / len;
	objPos.x = (Path[uiEnd].x - Path[uiStart].x) * Scalar + Path[uiStart].x;
	objPos.y = (Path[uiEnd].y - Path[uiStart].y) * Scalar + Path[uiStart].y;
	objPos.z = (Path[uiEnd].z - Path[uiStart].z) * Scalar + Path[uiStart].z;
}

Then call via:


for (UINT i = 0; i < MaxPathCount; i++)
    SetPath(i, i+1);

Make sure you #define MaxPathCount to be the maximum number of paths. Don't go out of subscript btw.

The following might not work unless you put them in order properly as I said above.


#define MaxPath 6

Path[0].x = -2.5f; Path[0].y = 1.0f; Path[0].z = 0.0f;
Path[1].x =  2.5f; Path[1].y = 1.0f; Path[1].z = 0.0f;
Path[2].x =  2.5f; Path[2].y = 1.0f; Path[2].z = 0.0f;
Path[3].x = -2.5f; Path[3].y = 1.0f; Path[3].z = 0.0f;
Path[4].x = -2.5f; Path[4].y = -1.0f; Path[4].z = 0.0f;
Path[5].x = -2.5f; Path[5].y = 1.0f; Path[5].z = 0.0f;

Thanks for replying,i have done what you suggested but it seems the triangle still seems to go from right to left and not back again


void SetPath(UINT uiStart, UINT uiEnd,float Scalar)
{
diff.x = Path[uiEnd].x - Path[uiStart].x;
diff.y = Path[uiEnd].y - Path[uiStart].y;
diff.z = Path[uiEnd].z - Path[uiStart].z;
 
float len = (float)sqrt((diff.x * diff.x +
  diff.y * diff.y +
diff.z * diff.z));
Scalar = Scalar / len;
objPos.x = (Path[uiEnd].x - Path[uiStart].x) * Scalar + Path[uiStart].x;
objPos.y = (Path[uiEnd].y - Path[uiStart].y) * Scalar + Path[uiStart].y;
objPos.z = (Path[uiEnd].z - Path[uiStart].z) * Scalar + Path[uiStart].z;
}
 
//Paths

 Path[0].x = -0.1f; Path[0].y = 0.0f; Path[0].z = 0.0f;
  Path[1].x =  0.1f; Path[1].y = 0.0f; Path[1].z = 0.0f;
  Path[2].x =  0.1f; Path[2].y = 0.0f; Path[2].z = 0.0f;
  Path[3].x = -0.1f; Path[3].y = 0.0f; Path[3].z = 0.0f;
  Path[4].x = 0.1f; Path[4].y = 0.0f; Path[4].z = 0.0f;
  Path[5].x = -0.1f; Path[5].y = 0.0f; Path[5].z = 0.0f;
 
//using the function

for (UINT i = 0; i < MaxPath; i++)
{
SetPath(i, i+1,Scalar);
}
 
:)

also maybe replace:


if(CurrentPath > 2) CurrentPath = 1;

with:


if(CurrentPath > MaxPathCount) CurrentPath = 0;

And oh dear sorry about the for loop I gave you... You need to be able to call that SetPath(...) every frame. Make CurrentPath global. So that it will remember the last frame's number. Then in your render loop:


SetPath(CurrentPath, CurrentPath + 1);
CurrentPath++;

Also as I said I would be best if you set up your Path[n].x to equal minus then plus alternatingly. Then you could add as many as you like but remember to change you MaxPathCount also. I hope this works for you.

I am kind of confused now, i did comment out the below code on your first suggestion,now use and not the forloop right?


if(Scalar >= 1.0f)
{
StartTime = (float)timeGetTime();
 
CurrentPath++;
 
if(CurrentPath > 2) CurrentPath = 1;
 
}

now i have

void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
 
    d3ddev->BeginScene();
 
    // select which vertex format we are using
    d3ddev->SetFVF(CUSTOMFVF);
 
    // SET UP THE PIPELINE
 
    D3DXMATRIX matRotateY;    // a matrix to store the rotation information
 
    static float index = 0.0f; index+=0.05f;    // an ever-increasing float value
 
    // build a matrix to rotate the model based on the increasing float value
    D3DXMatrixRotationY(&matRotateY, index);
 
    // tell Direct3D about our matrix
    d3ddev->SetTransform(D3DTS_WORLD, &matRotateY);
 
    D3DXMATRIX matView;    // the view transform matrix
 
    D3DXMatrixLookAtLH(&matView,
                       &D3DXVECTOR3 (0.0f, 0.0f, 5.0f),    // the camera position
                       &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),    // the look-at position
                       &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
 
    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView
 
    D3DXMATRIX matProjection;     // the projection transform matrix
 
    D3DXMatrixPerspectiveFovLH(&matProjection,
                               D3DXToRadian(45),    // the horizontal field of view
                               (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
                               0.1f,    // the near view-plane
                               100.0f);    // the far view-plane
 
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection
 
 
float Scalar = (float)timeGetTime();
Scalar = (Scalar - StartTime) * 0.003f;
 
if(Scalar >= 1.0f)
{
StartTime = (float)timeGetTime();
 
CurrentPath++;
 
if(CurrentPath > MaxPath) CurrentPath = 0;
 
}
 
SetPath(CurrentPath, CurrentPath + 1);
    CurrentPath++;
 
 
D3DXMATRIX mat;
//D3DXMatrixIdentity(&mat);
D3DXMatrixTranslation(&mat,objPos.x,objPos.y,objPos.z);
d3ddev->SetTransform(D3DTS_WORLD,&mat);
 
    // select the vertex buffer to display
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
 
    // copy the vertex buffer to the back buffer
    d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
 
    d3ddev->EndScene();
 
    d3ddev->Present(NULL, NULL, NULL, NULL);
}
:)

Sorry for the confusion. Ok so instead of:


float Scalar = (float)timeGetTime();
Scalar = (Scalar -StartTime) * 0.0003f;
 
if(CurrentPath == 1)
{
stVector diff;
diff.x = Path[1].x - Path[0].x;
diff.y = Path[1].y - Path[0].y;
diff.z = Path[1].z - Path[0].z;
 
float len = (float)sqrt((diff.x * diff.x +
                   diff.y * diff.y +
diff.z * diff.z));
Scalar = Scalar / len;
objPos.x = (Path[1].x - Path[0].x) * Scalar + Path[0].x;
objPos.y = (Path[1].y - Path[0].y) * Scalar + Path[0].y;
objPos.z = (Path[1].z - Path[0].z) * Scalar + Path[0].z;
}
else
{
stVector diff;
diff.x = Path[3].x - Path[2].x;
diff.x = Path[3].y - Path[2].y;
diff.x = Path[3].z - Path[2].z;
 
float len = (float)sqrt((diff.x * diff.x +
                    diff.y * diff.y +
diff.z * diff.z));
 
Scalar = Scalar / len;
objPos.x = (Path[3].x - Path[2].x) * Scalar + Path[2].x;
objPos.y = (Path[3].y - Path[2].y) * Scalar + Path[2].y;
objPos.z = (Path[3].z - Path[2].z) * Scalar + Path[2].z;
}
 
if(Scalar >= 1.0f)
{
StartTime = (float)timeGetTime();
 
CurrentPath++;
 
if(CurrentPath > 2) CurrentPath = 1;
 
}

May be try:


float Scalar = (float)timeGetTime();
Scalar = (Scalar -StartTime) * 0.0003f;

 
if(Scalar >= 1.0f)
{
    SetPath(CurrentPath, CurrentPath + 1, Scalar);
    StartTime = (float)timeGetTime(); 
    if((CurrentPath + 1) > MaxPathCount) 
        CurrentPath = 0; 
    else
        CurrentPath++;
}

What is happening is you can call SetPath(...) Every second then if within bounds increment CurrentPath else set to zero.

Thanks alot for the quick respone, so now its doing a teleport effect and not actually moving from the points, but its going through the paths, i dont think changing the scaler speed will fix it as its already set to slow

:)

Oops maybe the SetPath call needs to be just above the IF statement so that it sets all object's properties.

it seems this condition affects how far the triangle moves

if(Scalar >= 1.0f)

because that would only be for -1.0f and 1.0f, so what happens if the path is like -3.0f and 3.0f, a bigger scaler etc, because visually it just moves abit and goes to the next path

:)

This topic is closed to new replies.

Advertisement