yeah yeah i know what you might think, 'what didnt that asshole solve his problem already?' i have to agree, i am an asshole for still not being able to solve my collision problem. well, i thought i solved the hard part(the part where i create a function that shoots a ray into a triangle), even if i did solve this the right way , i still cant manage to check collision.
here's what i am trying to do to make my collision work :
1)i retrieve the vertex and index lists from the buffers
2)i make a loop, length is number of vertices /3
3)i pass three vertices,direction of my movement and the origin point of the player to the function that checks collision.
4)if there's a collision, i just add it's information to a list(so that if there's more than one collision point, i'll check which is the closest).
5)after the loop is over, i make a check if there was collision at all, if
there was not, i let my player move, if there was i just do nothing(for now).
**)right now i only check collision if i move toward the collision object, and not if i hit it.
but it still gives odd results, sometimes it finds collision with some parts of the collision model, while on some other parts or directions it will not find collision(same thing for when i am not moving toward the collision object).
so i try to do that like this:
get vertex & index lists from buffers:
void GetLists()
{
VerticesNum = new D3DXVECTOR3[Mesh->GetNumVertices()];
IndexNum = new short[Mesh->GetNumFaces()*3];
DWORD stride = Mesh->GetNumBytesPerVertex();
BYTE* vbptr = NULL;
BYTE* ibptr = NULL;
DWORD Istride = sizeof(short);
Mesh->LockIndexBuffer(0,(LPVOID*)&ibptr);
Mesh->LockVertexBuffer(0, (LPVOID*)&vbptr);
D3DXVECTOR3 *pos = VerticesNum;
short *pos2 = IndexNum;
for (DWORD i = 0; i < Mesh->GetNumVertices(); i++)
{
memcpy(pos, vbptr, sizeof(D3DXVECTOR3));
vbptr += stride;
pos++;
}
for (DWORD k = 0; k < Mesh->GetNumFaces()*3; k++)
{
memcpy(pos2, ibptr, sizeof(short));
ibptr += Istride;
pos2++;
}
Mesh->UnlockIndexBuffer();
Mesh->UnlockVertexBuffer();
up until here everything's fine?
then here's the part when i press forward
velx=-(float)cos(MainPlayer->rotz+rad_90)*sin(MainPlayer->rotx+rad_90) *10.5;
vely=-(float)sin(MainPlayer->rotz+rad_90) *sin(MainPlayer->rotx+rad_90) *10.5;
velz=-(float)sin(MainPlayer->rotx) *10.5;
D3DXVECTOR3 dir(velx,vely,velz);D3DXVECTOR3 origin(MainPlayer->x,MainPlayer->y,MainPlayer->z);
CollisionInfo lengthcount[3];short count =0;CollisionInfo max;max.length =0;bool cold=false;int countertwo=0;
//lengthcount holds the information if there's a collision
//count is not important here. cold is false if there was no collision.
//true data(defined globaly) just makes sure the vertices' are transformed to world space.
for(int i=0;i<rock->Mesh->GetNumVertices()/3;i++)
{
if(truedata == false){
rock->VerticesNum[rock->IndexNum[countertwo]].x+=rock->x;
rock->VerticesNum[rock->IndexNum[countertwo]].y+=rock->y;
rock->VerticesNum[rock->IndexNum[countertwo]].z+=rock->z;
rock->VerticesNum[rock->IndexNum[countertwo+1]].x+=rock->x;
rock->VerticesNum[rock->IndexNum[countertwo+1]].y+=rock->y;
rock->VerticesNum[rock->IndexNum[countertwo+1]].z+=rock->z;
rock->VerticesNum[rock->IndexNum[countertwo+2]].x+=rock->x;
rock->VerticesNum[rock->IndexNum[countertwo+2]].y+=rock->y;
rock->VerticesNum[rock->IndexNum[countertwo+2]].z+=rock->z;
}
//code block above transforms the list into world space from model space.
CollisionInfo col = Intersect(&rock->VerticesNum[rock->IndexNum[countertwo]],&rock->VerticesNum[rock->IndexNum[countertwo+1]],rock->VerticesNum[rock->IndexNum[countertwo+2]],dir,origin);
if (col.intersected == true)
{
//unimportant stuff
}
countertwo+=3;
}
truedata = true;
if(cold)
{
//unimportant stuff
}else{
MainPlayer->y+=vely;
MainPlayer->x+=velx;
MainPlayer->z+=velz;
SecondPlayer->y+=vely;
SecondPlayer->x+=velx;
SecondPlayer->z+=velz;
}
whew, alot of code, i tryed to clean it a bit of unimportant stuff so it would look smaller.
now the last part is the function that checks collision which is :
CollisionInfo Intersect(D3DXVECTOR3 *vVertex1, D3DXVECTOR3 *vVertex2, D3DXVECTOR3 vVertex3,D3DXVECTOR3 dir,D3DXVECTOR3 origin)
{
D3DXVECTOR3 vNormal;
D3DXVECTOR3 vNormal2;
D3DXVECTOR3 v1;
D3DXVECTOR3 v2;
D3DXVECTOR3 r1;
D3DXVECTOR3 r2;
D3DXVECTOR3 r3;
float d1;
float d2;
CollisionInfo cola;
float arr[3];//will hold information to check if point is inside triangle
D3DXVECTOR3 lol;
D3DXVec3Subtract(&v1, vVertex2, vVertex1);
D3DXVec3Subtract(&v2, &vVertex3, vVertex1);
D3DXVec3Cross(&vNormal, &v1, &v2);
D3DXVec3Normalize(&vNormal, &vNormal);
//above is a code to calculate normal
float DotProduct = D3DXVec3Dot(&vNormal,&dir);
if(DotProduct<=0){
cola.intersected = false;return cola;}
float d = -(vVertex2->x*vNormal.x+vVertex2->y*vNormal.y+vVertex2->z*vNormal.z);//plane equation
cola.length = -((D3DXVec3Dot(&origin,&vNormal)+d)/DotProduct);//t = -(Rayorigin*planeNormal+d)\(planenormal*direction)
D3DXVECTOR3 dirT = dir;
dirT.x*=cola.length;dirT.y*=cola.length;dirT.z*=cola.length;
D3DXVec3Add(&lol,&origin, &dirT);
D3DXVECTOR3 IntersectionPoint =lol;//calculate where is the intersection point
//now to calculate if the point is inside the triangle
D3DXVec3Subtract(&r1, vVertex1, &IntersectionPoint);
D3DXVec3Subtract(&r2, vVertex2, &IntersectionPoint);
D3DXVec3Subtract(&r3, &vVertex3, &IntersectionPoint);
origin.x*=-1; origin.y*=-1; origin.z*=-1;//invert the origin for the 'point in triangle' check.
//calculate side 1
D3DXVec3Cross(&vNormal2, &r1, &r2);
D3DXVec3Normalize(&vNormal2, &vNormal2);
d1=D3DXVec3Dot( &vNormal2, &origin);
d2=3DXVec3Dot( &vNormal2, &IntersectionPoint);
arr[0] = d1+d2;
//calculate side 2
D3DXVec3Cross(&vNormal2, &r3, &r2);
D3DXVec3Normalize(&vNormal2, &vNormal2);
d1=D3DXVec3Dot(&vNormal2, &origin);
d2=D3DXVec3Dot( &vNormal2, &IntersectionPoint);
arr[1] = d1+d2;
//calculate side 3
D3DXVec3Cross(&vNormal2, &r1, &r3);
D3DXVec3Normalize(&vNormal2, &vNormal2);
d1=D3DXVec3Dot( &vNormal2, &origin);
d2=D3DXVec3Dot( &vNormal2, &IntersectionPoint);
arr[2] = d1+d2;
if(arr[0]<0 || arr[1]<0 || arr[2]<0 ){cola.intersected=false;return cola;}else{
cola.intersected=true;
cola.normal=vNormal;
return cola;
}
}
yes, code is not clean.
i've been debugging this for almost 2 weeks and i still didnt manage to find out what i did wrong there.
does anyone see something wrong here?
i'll appreciate help very much, i cant wait to be done with this already.
thanks in advance, Bru.
[Edited by - Bru on March 16, 2009 11:47:22 AM]