📄 collisiondetection.cpp.svn-base
字号:
//关于我函数之间的调用关系和层次结构,参见我论文的30,31,32页的3.5节和4.1节。
//关于数据类型和数据结构的相关信息,参见我论文的33,34页的4.2.1节和4.2.2节。
#include "CollisionDetection.h"
CollisionDetection::CollisionDetection(void)
{
}
CollisionDetection::~CollisionDetection(void)
{
}
//关于这个函数的实现及原理参见我论文41,42页的4.4.1节。
void CollisionDetection::DectectionHumanAndBuilding(GameObject_Str* human, Building* building)
{
float x = building->lenX * 0.5 + human->radius;
float z = building->lenZ * 0.5 + human->radius;
Vertex v = building->pos;
float rotY = building->rotY*0.0174533f;
float sin = sinf(rotY);
float cos = cosf(rotY);
Vertex v1,v2,v3,v4; //将建筑物的局部坐标转化成全局坐标
v1.x = z*sin + x*cos + v.x;
v1.z = z*cos - x*sin + v.z;
v2.x = z*sin + (-x)*cos + v.x;
v2.z = z*cos - (-x)*sin + v.z;
v3.x = (-z)*sin + (-x)*cos + v.x;
v3.z = (-z)*cos - (-x)*sin + v.z;
v4.x = (-z)*sin + x*cos + v.x;
v4.z = (-z)*cos - x*sin + v.z;
if(CollisionDetectionMath::IsLineSegmentCutBydQuad(human->oldPos,&(human->newPos),v1,v2,v3,v4))
human->collide = true;
}
//关于这个函数的实现及原理参见我论文42页的4.4.2节。
void CollisionDetection::DectectionHumanAndTree(GameObject_Str* human, Tree* tree)
{
float r = tree->info->r + human->radius;
if(CollisionDetectionMath::IsLineSegmentCutByCircle(human->oldPos,&(human->newPos),tree->center,r))
human->collide = true;
}
//关于这个函数的实现及原理参见我论文42,43页的4.4.3节。
void CollisionDetection::DectectionOfTwoHuman(GameObject_Str* human1, GameObject_Str* human2)
{
float x = human2->lenX * 0.5 + human1->radius;
float z = human2->lenZ * 0.5 + human1->radius;
Vertex v = human2->oldPos;
Vertex vn = human2->newPos;
float rotY = human2->rotY*0.0174533f;
float sin = sinf(rotY);
float cos = cosf(rotY);
Vertex v1,v2,v3,v4,v5,v6,v7,v8;
v1.x = z*sin + x*cos + v.x;
v1.z = z*cos - x*sin + v.z;
v2.x = z*sin + (-x)*cos + v.x;
v2.z = z*cos - (-x)*sin + v.z;
v3.x = (-z)*sin + (-x)*cos + v.x;
v3.z = (-z)*cos - (-x)*sin + v.z;
v4.x = (-z)*sin + x*cos + v.x;
v4.z = (-z)*cos - x*sin + v.z;
v5.x = z*sin + x*cos + vn.x;
v5.z = z*cos - x*sin + vn.z;
v6.x = z*sin + (-x)*cos + vn.x;
v6.z = z*cos - (-x)*sin + vn.z;
v7.x = (-z)*sin + (-x)*cos + vn.x;
v7.z = (-z)*cos - (-x)*sin + vn.z;
v8.x = (-z)*sin + x*cos + vn.x;
v8.z = (-z)*cos - x*sin + vn.z;
if(CollisionDetectionMath::IsLineSegmentCutBydQuad(human1->oldPos,&(human1->newPos),v1,v2,v3,v4))
human1->collide = true;
if(CollisionDetectionMath::IsLineSegmentCutBydQuad(human1->oldPos,&(human1->newPos),v1,v2,v3,v4))
human1->collide = true;
}
void CollisionDetection::DectectionFireBallAndBuilding(FireBall* fireball, Building* building)
{
float x = building->lenX * 0.5 + fireball->radius;
float z = building->lenZ * 0.5 + fireball->radius;
Vertex v = building->pos;
float rotY = building->rotY*0.0174533f;
float sin = sinf(rotY);
float cos = cosf(rotY);
Vertex v1,v2,v3,v4;
v1.x = z*sin + x*cos + v.x;
v1.z = z*cos - x*sin + v.z;
v2.x = z*sin + (-x)*cos + v.x;
v2.z = z*cos - (-x)*sin + v.z;
v3.x = (-z)*sin + (-x)*cos + v.x;
v3.z = (-z)*cos - (-x)*sin + v.z;
v4.x = (-z)*sin + x*cos + v.x;
v4.z = (-z)*cos - x*sin + v.z;
if(CollisionDetectionMath::IsLineSegmentCutBydQuadExtendTo3D(fireball->oldPos,&(fireball->newPos),v1,v2,v3,v4,building->pos.y + building->lenY))
{
fireball->collide = true;
fireball->collideId = -1;
}
}
void CollisionDetection::DectectionFireBallAndTree(FireBall* fireball, Tree* tree)
{
float r = tree->info->r + fireball->radius;
if(CollisionDetectionMath::IsLineSegmentCutByCircleExtendTo3D(fireball->oldPos,&(fireball->newPos),tree->center,r,tree->center.y + 130))
{
fireball->collide = true;
fireball->collideId = -1;
}
}
void CollisionDetection::DectectionFireBallAndHuman(FireBall* fireball, GameObject_Str* human)
{
float x = human->lenX * 0.5 + fireball->radius;
float z = human->lenZ * 0.5 + fireball->radius;
Vertex v = human->oldPos;
Vertex vn = human->newPos;
float rotY = human->rotY*0.0174533f;
float sin = sinf(rotY);
float cos = cosf(rotY);
Vertex v1,v2,v3,v4,v5,v6,v7,v8;
v1.x = z*sin + x*cos + v.x;
v1.z = z*cos - x*sin + v.z;
v2.x = z*sin + (-x)*cos + v.x;
v2.z = z*cos - (-x)*sin + v.z;
v3.x = (-z)*sin + (-x)*cos + v.x;
v3.z = (-z)*cos - (-x)*sin + v.z;
v4.x = (-z)*sin + x*cos + v.x;
v4.z = (-z)*cos - x*sin + v.z;
v5.x = z*sin + x*cos + vn.x;
v5.z = z*cos - x*sin + vn.z;
v6.x = z*sin + (-x)*cos + vn.x;
v6.z = z*cos - (-x)*sin + vn.z;
v7.x = (-z)*sin + (-x)*cos + vn.x;
v7.z = (-z)*cos - (-x)*sin + vn.z;
v8.x = (-z)*sin + x*cos + vn.x;
v8.z = (-z)*cos - x*sin + vn.z;
if(CollisionDetectionMath::IsLineSegmentCutBydQuadExtendTo3D(fireball->oldPos,&(fireball->newPos),v1,v2,v3,v4,human->newPos.y + human->lenY))
{
fireball->collide = true;
fireball->collideId = human ->unique_id;
}
if(CollisionDetectionMath::IsLineSegmentCutBydQuadExtendTo3D(fireball->oldPos,&(fireball->newPos),v1,v2,v3,v4,human->newPos.y + human->lenY))
{
fireball->collide = true;
fireball->collideId = human ->unique_id;
}
}
//通过计算火球经过的地域,对每个三角形进行碰撞检测。
void CollisionDetection::DectectionFireBallAndLand(FireBall* fireball)
{
int maxx,minx,maxz,minz;
int i,j;
bool s1,s2;
int mapsize = map.getLandScape()->m_MapSize*TERRAIN_MULTIPL;
int over = 0;
if (fireball->newPos.x > fireball->oldPos.x)
{
maxx = (int)(fireball->newPos.x / TERRAIN_MULTIPL);
minx = (int)(fireball->oldPos.x / TERRAIN_MULTIPL);
}
else
{
minx = (int)(fireball->newPos.x / TERRAIN_MULTIPL);
maxx = (int)(fireball->oldPos.x / TERRAIN_MULTIPL);
}
if (fireball->newPos.z > fireball->oldPos.z)
{
maxz = (int)(fireball->newPos.z / TERRAIN_MULTIPL);
minz = (int)(fireball->oldPos.z / TERRAIN_MULTIPL);
}
else
{
minz = (int)(fireball->newPos.z / TERRAIN_MULTIPL);
maxz = (int)(fireball->oldPos.z / TERRAIN_MULTIPL);
}
//边界处理
if(maxx>map.getLandScape()->m_MapSize) {over++;maxx = map.getLandScape()->m_MapSize;}
if(maxz>map.getLandScape()->m_MapSize) {over++;maxz = map.getLandScape()->m_MapSize;}
if(minx<0) {over++;minx = 0;}
if(minz<0)
{
over++;
minz = 0;
}
for (i = minx ; i <= maxx; i++ )
{
for (j = minz; j <= maxz ; j++ )
{
Vertex v1(i*TERRAIN_MULTIPL, LandScape::m_HeightMap[ (int) ( i + j * LandScape::m_MapSize) ] , j*TERRAIN_MULTIPL);
Vertex v2( (i+1)*TERRAIN_MULTIPL , LandScape::m_HeightMap[ (int) ( (i+1) + j * LandScape::m_MapSize ) ] , j*TERRAIN_MULTIPL);
Vertex v3(i*TERRAIN_MULTIPL , LandScape::m_HeightMap[ (int) ( i + (j+1) * LandScape::m_MapSize ) ] , (j+1)*TERRAIN_MULTIPL );
Vertex v4( (i+1)*TERRAIN_MULTIPL , LandScape::m_HeightMap[ (int) ( (i+1) + (j+1) * LandScape::m_MapSize ) ] , (j+1)*TERRAIN_MULTIPL);
s1 = CollisionDetectionMath::IsLineSegmentCutByTriangle(fireball->oldPos,&(fireball->newPos),v1,v2,v3);
s2 = CollisionDetectionMath::IsLineSegmentCutByTriangle(fireball->oldPos,&(fireball->newPos),v4,v2,v3);
if( s1 || s2 )
{
fireball->collide = true;
fireball->collideId = -1;
}
}
}
if(over) //如果越出边界,判定火球碰撞。
{
fireball->collide = true;
fireball->collideId = -1;
}
}
//这是提供给外界的接口。
void CollisionDetection::doCollisionDetection()
{
list<Building>::iterator iterBuilding;
list<Tree>::iterator iterTree;
list<GameObject>::iterator iterUnit;
list<GameObject>::iterator iterUnit2;
list<FireBall>::iterator iterFireBall;
if (player.NeedChecked == true)
{
iterBuilding = buildings.begin();
while(iterBuilding != buildings.end())
{
DectectionHumanAndBuilding(&player,&(*iterBuilding));
iterBuilding++;
}
iterTree = trees.begin();
while(iterTree != trees.end())
{
DectectionHumanAndTree(&player,&(*iterTree));
iterTree++;
}
iterUnit = units.begin();
while(iterUnit != units.end())
{
DectectionOfTwoHuman(&player,&(*iterUnit));
iterUnit++;
}
player.checked = true;
}
iterUnit = units.begin();
while(iterUnit != units.end())
{
if(iterUnit->NeedChecked == true)
{
iterBuilding = buildings.begin();
while(iterBuilding != buildings.end())
{
DectectionHumanAndBuilding(&(*iterUnit),&(*iterBuilding));
iterBuilding++;
}
iterTree = trees.begin();
while(iterTree != trees.end())
{
DectectionHumanAndTree(&(*iterUnit),&(*iterTree));
iterTree++;
}
iterUnit2 = iterUnit;
while(iterUnit2 != units.end())
{
DectectionOfTwoHuman(&(*iterUnit),&(*iterUnit2));
iterUnit2++;
}
}
iterUnit->checked = true;
//////////cai xiao added this-----------------------------------------------------------------
// iterUnit->collide = false;
//-------------------------------------------------------------------------------------
iterUnit++;
}
iterFireBall = fireBalls.begin();
while(iterFireBall != fireBalls.end())
{
if (iterFireBall->NeedChecked == true)
{
iterBuilding = buildings.begin();
while(iterBuilding != buildings.end())
{
DectectionFireBallAndBuilding(&(*iterFireBall),&(*iterBuilding));
iterBuilding++;
}
iterTree = trees.begin();
while(iterTree != trees.end())
{
DectectionFireBallAndTree(&(*iterFireBall),&(*iterTree));
iterTree++;
}
iterUnit = units.begin();
while(iterUnit != units.end())
{
DectectionFireBallAndHuman(&(*iterFireBall),&(*iterUnit));
iterUnit++;
}
DectectionFireBallAndHuman(&(*iterFireBall),&player);
DectectionFireBallAndLand(&(*iterFireBall));
}
iterFireBall->checked = true;
iterFireBall++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -