⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 collisiondetection.cpp.svn-base

📁 自己做的小游戏
💻 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 + -