deargui-vpl/ref/virtools/Samples/Behaviors/Collision/Managers/CKCollisionManager_ToolsFunctions.cpp

194 lines
4.0 KiB
C++

/*************************************************************************/
/* File : CollisionManager.cpp */
/* */
/*************************************************************************/
#include "CKAll.h"
#include "CollisionManager.h"
//{secret}
int
CollisionManager::GetNearestFace(CK3dEntity* ent1,CK3dEntity* ent2)
{
float d2,d2min=10000000.0f;
int facemin=0;
VxVector pos,lpos;
VxVector* p0;
VxVector* p1;
VxVector* p2;
ent2->GetBaryCenter(&lpos);
ent1->InverseTransform(&pos,&lpos,ent2);
CKMesh* mesh = ent1->GetCurrentMesh();
if(!mesh) return -1;
CKVINDEX* fidx = mesh->GetFacesIndices();
int fc = mesh->GetFaceCount();
CKDWORD vStride;
BYTE* varray = (BYTE*)mesh->GetPositionsPtr(&vStride);
VxVector bary;
for(int i=0;i<fc;i++,fidx+=3) {
if(DotProduct(pos,mesh->GetFaceNormal(i)) > 0.0) {
p0 = (VxVector*)(varray+fidx[0]*vStride);
p1 = (VxVector*)(varray+fidx[1]*vStride);
p2 = (VxVector*)(varray+fidx[2]*vStride);
bary = (*p0+*p1+*p2)/3.0f;
// fisrst method
d2 = SquareMagnitude(bary - pos);
if(d2 < d2min) {
d2min = d2;
facemin = i;
}
/*
// second method
d2 = DotProduct(pos-bary,f->FaceNormal);
if(d2 < d2min) {
d2min = d2;
facemin = i;
}
*/
/*
// last method : NOT finshed : need to compare the two scalar product
d2 = SquareMagnitude(bary - pos);
if(d2 < d2min) {
float ps = DotProduct(pos-bary,f->FaceNormal);
d2min = d2;
facemin = i;
}
*/
}
}
return facemin;
}
//{secret}
int
CollisionManager::GetNearestFace(CK3dEntity* ent,VxVector& wpos)
{
CKMesh* mesh = ent->GetCurrentMesh();
if(!mesh) return -1;
int fc = mesh->GetFaceCount();
CKVINDEX* fidx = mesh->GetFacesIndices();
CKDWORD vStride;
BYTE* varray = (BYTE*)mesh->GetPositionsPtr(&vStride);
// we take the position of the given position in the entity referential
VxVector pos;
ent->InverseTransform(&pos,&wpos);
VxVector fpos,bary;
VxVector* p0;
float d2,d2min=10000000.0f;
int facemin=0;
for(int i=0;i<fc;++i,fidx+=3) {
p0 = (VxVector*)(varray+*fidx*vStride);
fpos = pos - *p0;
if ((d2 = DotProduct(fpos,mesh->GetFaceNormal(i))) > 0.0) {
/*
p1 = (VxVector*)(varray+fidx[1]*vStride);
p2 = (VxVector*)(varray+fidx[2]*vStride);
bary = (*p0+*p1+*p2)*0.3333333f;
// fisrst method
d2 = SquareMagnitude(bary - pos);
*/
if(d2 < d2min) {
d2min = d2;
facemin = i;
}
}
}
return facemin;
}
//{secret}
CKBOOL
CollisionManager::GetNearestVertex(CK3dEntity* ent1,CK3dEntity* ent2,VxVector& nearest)
{
// float d2,d2min=10000000.0f;
// int facemin=0;
VxVector pos1,pos2;
ent1->GetBaryCenter(&pos2);
ent1->Transform(&pos2,&pos2);
ent2->GetBaryCenter(&pos1);
ent2->Transform(&pos1,&pos1);
VxIntersectionDesc desc;
ent1->RayIntersection(&pos1,&pos2,&desc,NULL);
ent1->Transform(&nearest,&(desc.IntersectionPoint));
/*
CKMesh* mesh = ent1->GetCurrentMesh();
if(!mesh) return FALSE;
CKDWORD vStride;
BYTE* varray = (BYTE*)mesh->GetPositionsPtr(&vStride);
int vcount = mesh->GetVertexCount();
VxVector* p0;
VxVector bary;
for(int i=0;i<vcount;i++,varray += vStride) {
p0 = (VxVector*)varray;
// fisrst method
d2 = SquareMagnitude(*p0 - pos);
if(d2 < d2min) {
d2min = d2;
nearest = *p0;
}
}
*/
return TRUE;
}
//{secret}
int
CollisionManager::GetNearestVertex(CK3dEntity* ent,VxVector& wpos)
{
CKMesh* mesh = ent->GetCurrentMesh();
if(!mesh) return -1;
CKDWORD vStride;
BYTE* varray = (BYTE*)mesh->GetPositionsPtr(&vStride);
int vcount = mesh->GetVertexCount();
if(!vcount) return -1;
VxVector* p0;
float d2,d2min=10000000.0f;
int nearest;
// we take the position of the given position in the entity referential
VxVector pos;
ent->InverseTransform(&pos,&wpos);
// we iterate on each vertex to find the closest one from the
// position 3d we gave
for(int i=0;i<vcount;++i,varray += vStride) {
p0 = (VxVector*)varray;
// fisrst method
d2 = SquareMagnitude(*p0 - pos);
if(d2 < d2min) {
d2min = d2;
nearest = i;
}
}
return nearest;
}