Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
600 lines
16 KiB
C++
600 lines
16 KiB
C++
|
|
#include "Collision.h"
|
|
|
|
#include <stdio.h>
|
|
#define EPS 0.005f
|
|
///collision detection///
|
|
|
|
NewCCollisionDetection::NewCCollisionDetection() {
|
|
|
|
object = new CCollisionUnit;
|
|
m_bs = 0;
|
|
m_fs = 0;
|
|
faces = NULL;
|
|
m_FaceNum = 0;
|
|
|
|
|
|
|
|
}
|
|
NewCCollisionDetection::~NewCCollisionDetection() {
|
|
if(object != NULL)
|
|
delete object;
|
|
if(faces != NULL)
|
|
delete[] faces;
|
|
}
|
|
// Get Slide vector
|
|
D3DXVECTOR3 NewCCollisionDetection::SlidePolygonVector(D3DXVECTOR3 Velocity,D3DXVECTOR3 PlaneNormal) {
|
|
//((velocity dot planenormal) *planenormal) - velocity
|
|
|
|
|
|
D3DXVec3Normalize(&PlaneNormal,&PlaneNormal);
|
|
float distance = D3DXVec3Dot(&Velocity,&PlaneNormal);
|
|
D3DXVECTOR3 tmp = (-PlaneNormal) * distance;
|
|
tmp = tmp - Velocity;
|
|
D3DXVec3Normalize(&tmp,&tmp);
|
|
|
|
//tmp *=(-10.0f);
|
|
return tmp;
|
|
|
|
}
|
|
|
|
//return value : pos 에서의 거리
|
|
D3DXVECTOR3 NewCCollisionDetection::GetDistanceClosetPointOnLine(D3DXVECTOR3 pos,D3DXVECTOR3 a,D3DXVECTOR3 b){
|
|
//line 상에서의 충돌거리
|
|
|
|
D3DXVECTOR3 pline = pos - a;
|
|
D3DXVECTOR3 line = b-a;
|
|
|
|
|
|
float line_length = D3DXVec3Length(&line);
|
|
|
|
D3DXVec3Normalize(&line,&line);
|
|
//float line_length = D3DXVec3Length(&line);
|
|
|
|
// pline 에서 line 성분으로의 크기
|
|
float distance = D3DXVec3Dot(&line,&pline);
|
|
|
|
if(distance <0.0f) {
|
|
return a;
|
|
}
|
|
else if(distance > line_length) {
|
|
return b;
|
|
}
|
|
line.x = line.x * distance;
|
|
line.y = line.y * distance;
|
|
line.z = line.z * distance;
|
|
|
|
return (a + line);
|
|
}
|
|
D3DXVECTOR3 NewCCollisionDetection::GetDistanceClosetPointOnTriangle(D3DXVECTOR3 pos,D3DXVECTOR3 a,D3DXVECTOR3 b,D3DXVECTOR3 c) { // triangle 위의 충돌점 구하기
|
|
|
|
|
|
// triangle 상의 라인에 가장 가까운 거리의 point 와의 거리 vector
|
|
float plength[3] = {0.0f,0.0f,0.0f};
|
|
float min_length = 0.0f;
|
|
|
|
D3DXVECTOR3 tline[3];
|
|
|
|
D3DXVECTOR3 return_vec(0.0f,0.0f,0.0f);
|
|
tline[0] = GetDistanceClosetPointOnLine(pos,a,b);
|
|
tline[1] = GetDistanceClosetPointOnLine(pos,b,c);
|
|
tline[2] = GetDistanceClosetPointOnLine(pos,c,a);
|
|
|
|
plength[0] = D3DXVec3Length(&(pos-tline[0]));
|
|
plength[1] = D3DXVec3Length(&(pos-tline[1]));
|
|
plength[2] = D3DXVec3Length(&(pos-tline[2]));
|
|
|
|
for(int i=0;i<3;i++) {
|
|
if(i==0) {
|
|
min_length = plength[i];
|
|
return_vec = tline[i];
|
|
}
|
|
else{
|
|
if(min_length >plength[i]) {
|
|
min_length = plength[i];
|
|
return_vec = tline[i];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return return_vec;
|
|
}
|
|
|
|
bool NewCCollisionDetection::CheckCollisionSphere(D3DXVECTOR3 pos,D3DXVECTOR3 spherecenter,float sphererad) { // sphere과의 충돌 체크
|
|
|
|
D3DXVECTOR3 distancevec = pos - spherecenter;
|
|
float distance = D3DXVec3Length(&distancevec);
|
|
if(distance <= sphererad) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool NewCCollisionDetection::CheckInTriangle(D3DXVECTOR3 pos,D3DXVECTOR3 a,D3DXVECTOR3 b,D3DXVECTOR3 c){ // triangle 과의 충돌 체크
|
|
|
|
|
|
float length[3] = {0.0f,0.0f,0.0f};
|
|
double radian = 0.0f;
|
|
|
|
D3DXVECTOR3 pa = pos - a;
|
|
D3DXVECTOR3 pb = pos - b;
|
|
D3DXVECTOR3 pc = pos - c;
|
|
|
|
D3DXVec3Normalize(&pa,&pa);
|
|
D3DXVec3Normalize(&pb,&pb);
|
|
D3DXVec3Normalize(&pc,&pc);
|
|
|
|
length[0] = D3DXVec3Dot(&pa,&pb);
|
|
length[1] = D3DXVec3Dot(&pb,&pc);
|
|
length[2] = D3DXVec3Dot(&pc,&pa);
|
|
|
|
radian = acos(length[0]);
|
|
radian += acos(length[1]);
|
|
radian += acos(length[2]);
|
|
//radian = acos(length[0]);
|
|
// 360 도를 넘는가 검사
|
|
if(fabs(radian - (2*D3DX_PI)) <= 0.005)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
float NewCCollisionDetection::RayCollisionPlane(D3DXVECTOR3 rcenter,D3DXVECTOR3 rfwd,D3DXVECTOR3 plane,D3DXVECTOR3 plane_normal) {
|
|
|
|
//ax + by + cz = d
|
|
//d = -(a dot x)
|
|
float distance = -D3DXVec3Dot(&plane_normal,&plane);
|
|
|
|
float numer = D3DXVec3Dot(&plane_normal,&rcenter) + distance;
|
|
// 플레인 노말에서 ray 방향으로의 크기
|
|
float denom = D3DXVec3Dot(&plane_normal,&rfwd);
|
|
|
|
if (denom == 0)
|
|
return (-1.0f);
|
|
|
|
return (-(numer / denom));
|
|
}
|
|
|
|
float NewCCollisionDetection::RayCollisionSphere(D3DXVECTOR3 rcenter,D3DXVECTOR3 rfwd,D3DXVECTOR3 spherecenter,float sphererad) {
|
|
|
|
//ray 와 sphere사이의 거리 량 return
|
|
D3DXVECTOR3 distancevector = spherecenter - rcenter;
|
|
float distance = D3DXVec3Length(&distancevector);
|
|
float dotvector = D3DXVec3Dot(&distancevector,&rfwd);
|
|
// rad 획득
|
|
float rad = sphererad * sphererad - (distance * distance - dotvector * dotvector);
|
|
|
|
if(rad <0.0f)
|
|
return -1.0f;
|
|
|
|
return (dotvector - sqrt(rad));
|
|
|
|
}
|
|
/****/
|
|
|
|
CCOLLISIONSIDE NewCCollisionDetection::ClassifyPoint(D3DXVECTOR3 point, D3DXVECTOR3 plane, D3DXVECTOR3 plane_normal) {
|
|
//point와 plane의 관계 return
|
|
/*
|
|
if(fabs(plane.x) < 0.01) {
|
|
plane.x = 0.0f;
|
|
}
|
|
if(fabs(plane.y) < 0.01) {
|
|
plane.y = 0.0f;
|
|
}
|
|
if(fabs(plane.z) < 0.01) {
|
|
plane.z = 0.0f;
|
|
}
|
|
*/
|
|
D3DXVECTOR3 dir = plane - point;
|
|
//D3DXVec3Normalize(&dir,&dir);
|
|
|
|
float d = D3DXVec3Dot(&dir, &plane_normal);
|
|
|
|
if (d<-0.001f)
|
|
return CCOLLISIONFRONTSIDE;
|
|
else if (d>0.001f)
|
|
return CCOLLISIONBACKSIDE;
|
|
|
|
return CCOLLISIONONSIDE;
|
|
}
|
|
D3DXVECTOR3 NewCCollisionDetection::SetVectorEllipsoidSpace(D3DXVECTOR3 vector,D3DXVECTOR3 spacerad) {
|
|
|
|
D3DXVECTOR3 convert;
|
|
convert.x = vector.x / spacerad.x;
|
|
convert.y = vector.y / spacerad.y;
|
|
convert.z = vector.z / spacerad.z;
|
|
return convert;
|
|
|
|
}
|
|
bool NewCCollisionDetection::CheckPointInSphere(D3DXVECTOR3 point,D3DXVECTOR3 scenter,float rad) {
|
|
|
|
// rad는 이미 sphere space 로 변환된 상태에서의 비교이므로 1.0f 이다.
|
|
D3DXVECTOR3 tmp = point - scenter;
|
|
float tmp_length = D3DXVec3Length(&tmp);
|
|
|
|
if(tmp_length < rad)
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
// collision이 일어나는지 체크 함수
|
|
bool NewCCollisionDetection::CollisionCheck(CCollisionUnit *move_object,int faceindex) {
|
|
|
|
//bool CCollisionDetection::CollisionCheck(D3DXVECTOR3 pos,D3DXVECTOR3 rad,D3DXVECTOR3 velocity,
|
|
// triangle *polylist,int facenum,bool &col) {
|
|
|
|
bool return_value = false;
|
|
|
|
//plane
|
|
D3DXVECTOR3 plane;
|
|
D3DXVECTOR3 pnormal;
|
|
D3DXVECTOR3 line1,line2;
|
|
|
|
D3DXVECTOR3 UnitSphereCollisionPoint;
|
|
D3DXVECTOR3 UnitPlaneCollisionPoint;
|
|
D3DXVECTOR3 InTrianglePoint;
|
|
|
|
D3DXVECTOR3 UnitPos = move_object->m_UnitPos;
|
|
D3DXVECTOR3 UnitRad = move_object->m_UnitRad;
|
|
D3DXVECTOR3 UnitVelocity = move_object->m_UnitVelocity;
|
|
D3DXVECTOR3 UnitNormalVelocity = UnitVelocity;
|
|
|
|
float vellength = D3DXVec3Length(&UnitVelocity);
|
|
float distpolytosphere = 0.0f;
|
|
D3DXVec3Normalize(&UnitNormalVelocity,&UnitNormalVelocity);
|
|
//face collision check
|
|
D3DXVECTOR3 apoint,bpoint,cpoint;
|
|
CCOLLISIONSIDE CheckSide;
|
|
float dist;
|
|
// sphere space 로 setting
|
|
apoint = SetVectorEllipsoidSpace(faces[faceindex].a,UnitRad);
|
|
bpoint = SetVectorEllipsoidSpace(faces[faceindex].b,UnitRad);
|
|
cpoint = SetVectorEllipsoidSpace(faces[faceindex].c,UnitRad);
|
|
|
|
plane = apoint;
|
|
//pnormal = faces[faceindex].normal;
|
|
|
|
line1 = bpoint - apoint;
|
|
line2 = cpoint - bpoint;
|
|
/*
|
|
line1 = bpoint - apoint;
|
|
line2 = cpoint - apoint;
|
|
*/
|
|
D3DXVec3Cross(&pnormal,&line1,&line2);
|
|
|
|
D3DXVec3Normalize(&pnormal,&pnormal);
|
|
faces[faceindex].normal = pnormal;
|
|
//pos + (-pnormal)
|
|
|
|
UnitSphereCollisionPoint = move_object->m_UnitPos - pnormal;
|
|
|
|
//포인트가 앞면에 있는지 뒷면에 있는지 검사
|
|
CheckSide = ClassifyPoint(UnitSphereCollisionPoint,plane,pnormal);
|
|
|
|
if(CheckSide == CCOLLISIONBACKSIDE) {
|
|
/*
|
|
/// 모든점이 안에 있다고 가정할 시에 사용할 수 있다.
|
|
/// backside 로 나갈 시 무조건 전의 위치로 돌리는 루틴
|
|
move_object->m_bError = true;
|
|
move_object->m_bCollision = true;
|
|
return_value = true;
|
|
///
|
|
*/
|
|
dist = RayCollisionPlane(UnitSphereCollisionPoint,pnormal,plane,pnormal);
|
|
UnitPlaneCollisionPoint.x = UnitSphereCollisionPoint.x + (dist * pnormal.x);
|
|
UnitPlaneCollisionPoint.y = UnitSphereCollisionPoint.y + (dist * pnormal.y);
|
|
UnitPlaneCollisionPoint.z = UnitSphereCollisionPoint.z + (dist * pnormal.z);
|
|
m_bs++;
|
|
}
|
|
else {
|
|
//plane과 예상충돌지점
|
|
dist = RayCollisionPlane(UnitSphereCollisionPoint,UnitVelocity,plane,pnormal);
|
|
UnitPlaneCollisionPoint.x = UnitSphereCollisionPoint.x + (dist * UnitNormalVelocity.x);
|
|
UnitPlaneCollisionPoint.y = UnitSphereCollisionPoint.y + (dist * UnitNormalVelocity.y);
|
|
UnitPlaneCollisionPoint.z = UnitSphereCollisionPoint.z + (dist * UnitNormalVelocity.z);
|
|
m_fs++;
|
|
}// triangle안인지 검사
|
|
bool CTriangleValue = CheckInTriangle(UnitPlaneCollisionPoint,apoint,bpoint,cpoint);
|
|
|
|
if(CTriangleValue == false) {
|
|
|
|
InTrianglePoint = GetDistanceClosetPointOnTriangle(UnitPlaneCollisionPoint,apoint,bpoint,cpoint);
|
|
|
|
distpolytosphere = RayCollisionSphere(InTrianglePoint,-UnitNormalVelocity,move_object->m_UnitPos,1.0f);
|
|
//distpolytosphere = RayCollisionSphere(InTrianglePoint,-UnitNormalVelocity,move_object->m_UnitPos,move_object->m_UnitRad.y);
|
|
if(distpolytosphere>0.0f) {
|
|
UnitSphereCollisionPoint.x = InTrianglePoint.x + (distpolytosphere * (-UnitNormalVelocity.x));
|
|
UnitSphereCollisionPoint.y = InTrianglePoint.y + (distpolytosphere * (-UnitNormalVelocity.y));
|
|
UnitSphereCollisionPoint.z = InTrianglePoint.z + (distpolytosphere * (-UnitNormalVelocity.z));
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
InTrianglePoint = UnitPlaneCollisionPoint;
|
|
distpolytosphere = dist;
|
|
}
|
|
|
|
//if (CheckPointInSphere(InTrianglePoint,move_object->m_UnitPos,move_object->m_UnitRad.y)) { //point가 sphere 안에 있으면
|
|
if (CheckPointInSphere(InTrianglePoint,move_object->m_UnitPos,1.0f)) { //point가 sphere 안에 있으면
|
|
|
|
//move_object->m_UnitBeforePos = move_object->m_SphereCollisionPoint;
|
|
move_object->m_bError = true;
|
|
}
|
|
if ((distpolytosphere > 0) && (distpolytosphere <= vellength)) { //충돌
|
|
//***
|
|
// 충돌이 일어나지 않았거나 일어난 지점보다 더 안쪽에 있을때
|
|
if (((move_object->m_bCollision) ==false) || (distpolytosphere < (move_object->m_NearDistPolytoSphere))) {
|
|
move_object->m_NearDistPolytoSphere = distpolytosphere;
|
|
move_object->m_SphereCollisionPoint = UnitSphereCollisionPoint;
|
|
move_object->m_TriangleCollisionPoint = InTrianglePoint;
|
|
move_object->m_bCollision = true;
|
|
move_object->m_Index = faceindex;
|
|
move_object->m_PlaneOrigin = apoint;
|
|
move_object->m_PlaneNormal = pnormal;
|
|
col.a = faces[faceindex].a;
|
|
col.b = faces[faceindex].b;
|
|
col.c = faces[faceindex].c;
|
|
col.normal = faces[faceindex].normal;
|
|
|
|
return_value = true;
|
|
}
|
|
|
|
}
|
|
return return_value;
|
|
}
|
|
void NewCCollisionDetection::SetMeshInfo(triangle *polygon,int facenum) {
|
|
if(faces != NULL) {
|
|
delete[] faces;
|
|
faces = NULL;
|
|
}
|
|
faces = new triangle[facenum];
|
|
memcpy(faces,polygon,sizeof(triangle) * facenum);
|
|
m_FaceNum = facenum;
|
|
}
|
|
|
|
D3DXVECTOR3 NewCCollisionDetection::Check(D3DXVECTOR3 pos,D3DXVECTOR3 rad,D3DXVECTOR3 vel,D3DXVECTOR3 gravity){
|
|
D3DXVECTOR3 unitpos,unitvel;
|
|
D3DXVECTOR3 last_pos;
|
|
// 바닥 높이 읽어온다
|
|
/* float ground_height = GetHeight(pos.x,pos.y,pos.z);
|
|
// 중력 적용
|
|
//if(vel.x != 0.0f || vel.y != 0.0f || vel.z != 0.0f)
|
|
if(ground_height >0.0f) {
|
|
printf("");
|
|
}
|
|
if(pos.y > (ground_height + (rad.y + 20.0f)))
|
|
vel +=gravity;
|
|
*/
|
|
vector3 t_pos;
|
|
vector3 t_vel;
|
|
|
|
t_vel.x = vel.x;
|
|
t_vel.y= vel.y;
|
|
t_vel.z = vel.z;
|
|
|
|
t_pos.x = pos.x;
|
|
t_pos.y = pos.y;
|
|
t_pos.z = pos.z;
|
|
|
|
matrix matInHousePos;
|
|
matInHousePos.Translation(t_pos);
|
|
matInHousePos=matInHousePos*m_LocalInvPosMatrix;
|
|
t_pos=matInHousePos.GetLoc();
|
|
|
|
matrix matInHouseVel;
|
|
matInHouseVel.Translation(t_vel);
|
|
matInHouseVel=matInHouseVel*m_LocalInvRotMatrix;
|
|
t_vel=matInHouseVel.GetLoc();
|
|
|
|
unitpos.x = t_pos.x;
|
|
unitpos.y = t_pos.y;
|
|
unitpos.z = t_pos.z;
|
|
|
|
unitvel.x = t_vel.x;
|
|
unitvel.y = t_vel.y;
|
|
unitvel.z = t_vel.z;
|
|
|
|
/* // 비교 sphere 좌표계로 전환
|
|
unitpos.x = pos.x / rad.x;
|
|
unitpos.y = pos.y / rad.y;
|
|
unitpos.z = pos.z / rad.z;
|
|
|
|
unitvel.x = vel.x / rad.x;
|
|
unitvel.y = vel.y / rad.y;
|
|
unitvel.z = vel.z / rad.z;
|
|
*/
|
|
|
|
// last_pos = Collision(pos,vel);
|
|
last_pos = Collision(unitpos,unitvel);
|
|
|
|
|
|
last_pos.x = last_pos.x * rad.x;
|
|
last_pos.y = last_pos.y * rad.y;
|
|
last_pos.z = last_pos.z * rad.z;
|
|
|
|
return last_pos;
|
|
|
|
}
|
|
|
|
D3DXVECTOR3 NewCCollisionDetection::Collision(D3DXVECTOR3 pos,D3DXVECTOR3 velocity) {
|
|
|
|
D3DXVECTOR3 tmppos;
|
|
|
|
D3DXVECTOR3 nextpos = pos + velocity;
|
|
|
|
float vellength = D3DXVec3Length(&velocity);
|
|
if(vellength < EPS)
|
|
return pos;
|
|
|
|
object->m_UnitVelocity = velocity;
|
|
object->m_UnitPos = pos;
|
|
object->m_NearDistPolytoSphere = -1;
|
|
object->m_bCollision = false;
|
|
object->m_bError = false;
|
|
|
|
|
|
for(int i=0;i<m_FaceNum;i++) {
|
|
CollisionCheck(object,i);
|
|
}
|
|
|
|
m_fs = m_bs =0;
|
|
|
|
if(object->m_bCollision) { // collision 발생
|
|
|
|
char buf[256] = {0};
|
|
|
|
|
|
sprintf(buf,"충돌 이라니깐.. index : %d",object->m_Index);
|
|
MessageBox(NULL,buf,"test",MB_OK);
|
|
|
|
|
|
// if (object->m_bError) { // float error 범위 안이면 전의 위치로 되돌리기
|
|
// 만일 sphere 반지름 보다 이동거리가 작을시 끼어버리는 문제 발생할 수있다.
|
|
/* D3DXVECTOR3 tmp_comp = (object->m_UnitBeforePos) - pos;
|
|
|
|
if(D3DXVec3Length(&tmp_comp) <1.0f) { //낌 방지
|
|
//1.0 으로 맟추어 준다
|
|
SetVectorLength(tmp_comp,1.0f);
|
|
return (pos + tmp_comp);
|
|
}
|
|
else*/
|
|
return object->m_UnitBeforePos;
|
|
// }
|
|
D3DXVECTOR3 newpos;
|
|
|
|
if (object->m_NearDistPolytoSphere >= EPS) {
|
|
|
|
D3DXVECTOR3 tmp_v = velocity;
|
|
SetVectorLength(tmp_v,object->m_NearDistPolytoSphere-EPS);
|
|
newpos = object->m_UnitPos + tmp_v;
|
|
}
|
|
else
|
|
newpos = object->m_UnitPos;
|
|
|
|
|
|
// slide plane
|
|
|
|
D3DXVECTOR3 SlidePlane = object->m_TriangleCollisionPoint;
|
|
D3DXVECTOR3 SlideNormal = newpos - (object->m_TriangleCollisionPoint);
|
|
|
|
D3DXVec3Normalize(&SlideNormal,&SlideNormal);
|
|
|
|
//SlideNormal *=(-1.0f);
|
|
//////////////
|
|
|
|
float slidelength = RayCollisionPlane(nextpos,SlideNormal,SlidePlane,SlideNormal);
|
|
|
|
D3DXVECTOR3 newnextPoint;
|
|
|
|
//새로운 pos
|
|
|
|
newnextPoint.x = nextpos.x + slidelength * SlideNormal.x;
|
|
newnextPoint.y = nextpos.y + slidelength * SlideNormal.y;
|
|
newnextPoint.z = nextpos.z + slidelength * SlideNormal.z;
|
|
|
|
D3DXVECTOR3 newVelocityVector = newnextPoint - object->m_TriangleCollisionPoint;
|
|
|
|
/* float newVelocityLength = D3DXVec3Length(&newVelocityVector);
|
|
if(newVelocityLength < 0.1f) {
|
|
|
|
D3DXMATRIX trans_matrix;
|
|
D3DXMATRIX pos_matrix;
|
|
D3DXMatrixIdentity(&trans_matrix);
|
|
D3DXMatrixIdentity(&pos_matrix);
|
|
|
|
pos_matrix._41 = newVelocityVector.x;
|
|
pos_matrix._42 = newVelocityVector.y;
|
|
pos_matrix._43 = newVelocityVector.z;
|
|
|
|
D3DXMatrixRotationYawPitchRoll(&trans_matrix,D3DXToRadian(45.0f),D3DXToRadian(45.0f),D3DXToRadian(45.0f));
|
|
D3DXMatrixMultiply(&pos_matrix,&pos_matrix,&trans_matrix);
|
|
|
|
newVelocityVector.x = pos_matrix._41;
|
|
newVelocityVector.y = pos_matrix._42;
|
|
newVelocityVector.z = pos_matrix._43;
|
|
|
|
|
|
}*/
|
|
//D3DXVECTOR3 newVelocityVector = SlidePolygonVector(object->m_UnitVelocity,SlideNormal);
|
|
/*
|
|
|
|
D3DXVECTOR3 SlidePlane = object->m_TriangleCollisionPoint;
|
|
D3DXVECTOR3 SlideNormal = newpos - (object->m_TriangleCollisionPoint);
|
|
//SlideNormal *=(-1.0f);
|
|
|
|
//**
|
|
float slidelength = RayCollisionPlane(nextpos,SlideNormal,SlidePlane,SlideNormal);
|
|
D3DXVECTOR3 newnextPoint;
|
|
//새로운 pos
|
|
newnextPoint.x = nextpos.x + slidelength * SlideNormal.x;
|
|
newnextPoint.y = nextpos.y + slidelength * SlideNormal.y;
|
|
newnextPoint.z = nextpos.z + slidelength * SlideNormal.z;
|
|
|
|
D3DXVECTOR3 newVelocityVector = newnextPoint - object->m_TriangleCollisionPoint;
|
|
|
|
//D3DXVECTOR3 newVelocityVector = SlidePolygonVector(object->m_UnitVelocity,SlideNormal);
|
|
*/
|
|
object->m_UnitBeforePos = pos;
|
|
|
|
return Collision(newpos,newVelocityVector);
|
|
|
|
}
|
|
else { // no collision
|
|
float vec_length = D3DXVec3Length(&velocity);
|
|
D3DXVECTOR3 vec = velocity;
|
|
|
|
SetVectorLength(vec,vec_length - EPS);
|
|
object->m_UnitBeforePos = pos;
|
|
|
|
return (pos + vec);
|
|
|
|
}
|
|
|
|
}
|
|
/*****/
|
|
void NewCCollisionDetection::SetVectorLength(D3DXVECTOR3 &vec,float veclength) {
|
|
|
|
|
|
float len = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
|
|
|
|
/* vec.x *= (veclength - EPS)/len;
|
|
vec.y *= (veclength - EPS)/len;
|
|
vec.z *= (veclength - EPS)/len;
|
|
*/
|
|
vec.x *= (veclength)/len;
|
|
vec.y *= (veclength)/len;
|
|
vec.z *= (veclength)/len;
|
|
}
|
|
float NewCCollisionDetection::GetHeight(float x,float y,float z) {
|
|
int i;
|
|
for(i=0;i<m_FaceNum;i++) {
|
|
if((faces[i].a.y == faces[i].b.y) && (faces[i].b.y== faces[i].c.y) && (faces[i].a.y == faces[i].c.y)) { // polygon 이 바닥일 경우
|
|
D3DXVECTOR3 check_pos;
|
|
check_pos.x = x;
|
|
check_pos.z = z;
|
|
check_pos.y = faces[i].a.y;
|
|
|
|
if(CheckInTriangle(check_pos,faces[i].a,faces[i].b,faces[i].c)) { //얻고자 하는 위치
|
|
if((faces[i].a.y) < y) // 이 face가 내 위치 보다 아래에 위치 할시에
|
|
return (faces[i].a.y);
|
|
}
|
|
}
|
|
}
|
|
return 0.0f;
|
|
}
|
|
void NewCCollisionDetection::SetLocalVector(float x,float y,float z,float vx,float vy,float vz,float vellength,matrix inv_pos,matrix inv_rot) {
|
|
m_LocalPos.x = x;
|
|
m_LocalPos.y = y;
|
|
m_LocalPos.z = z;
|
|
|
|
m_LocalVelocityNormalize.x = vx;
|
|
m_LocalVelocityNormalize.y = vy;
|
|
m_LocalVelocityNormalize.z = vz;
|
|
|
|
m_LocalVelocityLength = vellength;
|
|
m_LocalInvPosMatrix = inv_pos;
|
|
m_LocalInvRotMatrix = inv_rot;
|
|
} |