CBombBonus::CBombBonus(CBombBonusType *pType,IEntity *piOwner) { m_sClassName="CBombBonus"; m_sName="BombBonus"; m_pType=pType; m_piCamera=NULL; m_dwDamageType=DAMAGE_TYPE_NONE; m_piOwner=piOwner; m_dRadius=m_pType->DesignGetRadius(); m_bInPlayAreaAnyTime=false; if(m_piOwner) { SUBSCRIBE_TO_CAST(m_piOwner,IEntityEvents); m_vOriginalPosition=m_piOwner->GetPhysicInfo()->vPosition; } if(m_pType->m_PlayAreaManager.m_piPlayAreaManager) { CVector vStart,vEnd; CVector vCameraPos; m_pType->m_PlayAreaManager.m_piPlayAreaManager->GetCameraRoute(&vStart,&vEnd); m_piCamera=m_pType->m_PlayAreaManager.m_piPlayAreaManager->GetCamera(); m_PlayAreaPlane=CPlane(AxisPosY,vStart); CVector vCut; if(m_piCamera){vCameraPos=m_piCamera->GetPosition();} if(m_PlayAreaPlane.Cut(m_vOriginalPosition,vCameraPos,&vCut)) { m_PhysicInfo.vPosition=vCut; } } }
IEntity *CLiveBonusType::CreateInstance(IEntity *piParent,unsigned int dwCurrentTime) { CLiveBonus *piEntity=new CLiveBonus(this); SPhysicInfo *pPhysicInfo=piEntity->GetPhysicInfo(); InitializeEntity(piEntity,dwCurrentTime); // Se posiciona el bonus en el plano aereo, en el juego no hay bonus de armas entregados por unidades // de tierra, pero just in case CVector vPosition=pPhysicInfo->vPosition=piParent?piParent->GetPhysicInfo()->vPosition:Origin; CVector vStart,vEnd; CVector vCameraPos; if(m_PlayAreaManager.m_piPlayAreaManager) { m_PlayAreaManager.m_piPlayAreaManager->GetCameraRoute(&vStart,&vEnd); IGenericCamera *piCamera=m_PlayAreaManager.m_piPlayAreaManager->GetCamera(); if(piCamera){vCameraPos=piCamera->GetPosition();} REL(piCamera); } CPlane playAreaPlane=CPlane(AxisPosY,vStart); CVector vCut; if(playAreaPlane.Cut(vPosition,vCameraPos,&vCut)) { pPhysicInfo->vPosition=vCut; } piEntity->SetState(eLiveBonusState_Normal,ANIMATION_RANDOM); piEntity->SetInitialVelocity(); return piEntity; }
CBSPTree::CBSPTree( CModel *model ): _root(0){ for( int i=0;i<model->Surfaces().size();++i ){ CModelSurface *surf=(CModelSurface*)model->Surfaces()[i]->Copy(); cout<<"Adding surface, verts="<<surf->Vertices().size()<<", tris="<<surf->Triangles().size()<<endl; _surfaces.push_back( surf ); } vector<CPolygon*> polys; for( int i=0;i<_surfaces.size();++i ){ CModelSurface *surf=_surfaces[i]; vector<int> verts(3); for( vector<CTriangle>::const_iterator it=surf->Triangles().begin();it!=surf->Triangles().end();++it ){ const CTriangle &tri=*it; verts[0]=tri.vertices[0]; verts[1]=tri.vertices[1]; verts[2]=tri.vertices[2]; CPolygon *poly=new CPolygon( surf,verts ); polys.push_back( new CPolygon( surf,verts ) ); } } if( !polys.size() ){ _root=new CBSPNode( CPlane( CVec3(0,1,0),0 ) ); return; } _root=new CBSPNode( polys[0]->Plane() ); for( int i=1;i<polys.size();++i ){ _root->InsertPlane( polys[i] ); } for( int i=0;i<polys.size();++i ){ _root->InsertLeaf( polys[i] ); } for( int i=0;i<polys.size();++i ){ // _root->InsertPolygon( polys[i] ); } CPlane plane( CVec3(0,1,0),-5 ); // _root=new CBSPNode( plane,new CBSPNode( 1 ),0 ); _hpSurface=new CModelSurface; CPolygon *poly=new CPolygon( _hpSurface,plane,CBox( CVec3(-50),CVec3(50) ) ); CBSPNode *bits[2]; _root->Split( poly,bits ); _root=new CBSPNode( plane,bits[0],0 ); for( int i=0;i<polys.size();++i ){ _root->InsertPolygon( polys[i] ); } }
void CPlayAreaManager::ProcessFrame(unsigned int dwCurrentTime,double dTimeFraction) { if(!m_bStarted){return;} UpdatePlayCameraPosition(); if(m_bMovingCamera && m_vPlayMovementPos.c[0]<m_vCameraRouteEnd.c[0]) { m_vPlayMovementPos.c[0]+=dTimeFraction*m_dPlayMovementSpeed; if(m_vPlayMovementPos.c[0]>m_vCameraRouteEnd.c[0]) { m_vPlayMovementPos.c[0]=m_vCameraRouteEnd.c[0]; } } CalculateAirPlayArea(); CVector vCameraPos=m_vPlayMovementPos+AxisPosY*m_dCameraDistanceFromPlayer; CVector vRect[4]; vRect[0]=CVector(m_vVisibleAirPlayAreaMins.c[0],m_vVisibleAirPlayAreaMins.c[1],m_vVisibleAirPlayAreaMins.c[2]); vRect[1]=CVector(m_vVisibleAirPlayAreaMins.c[0],m_vVisibleAirPlayAreaMins.c[1],m_vVisibleAirPlayAreaMaxs.c[2]); vRect[2]=CVector(m_vVisibleAirPlayAreaMaxs.c[0],m_vVisibleAirPlayAreaMins.c[1],m_vVisibleAirPlayAreaMaxs.c[2]); vRect[3]=CVector(m_vVisibleAirPlayAreaMaxs.c[0],m_vVisibleAirPlayAreaMins.c[1],m_vVisibleAirPlayAreaMins.c[2]); m_PlayArea.nPlaneCount=2; m_PlayArea.planes[SPlayAreaInfo::Far]=CPlane(vCameraPos,vRect[3],vRect[2]); m_PlayArea.planes[SPlayAreaInfo::Near]=CPlane(vCameraPos,vRect[1],vRect[0]); unsigned x; for(x=0;x<m_vElements.size();x++) { IPlayAreaElement *piElement=m_vElements[x].m_piElement; piElement->ProcessFrame(m_vPlayMovementPos,&m_PlayArea,dwCurrentTime,dTimeFraction); } for(x=0;x<m_vEntityLayerElements.size();x++) { IPlayAreaElement *piElement=m_vEntityLayerElements[x].m_piElement; piElement->ProcessFrame(m_vPlayMovementPos,&m_PlayArea,dwCurrentTime,dTimeFraction); } for(x=0;x<m_vDynamicElements.size();x++) { IPlayAreaElement *piElement=m_vDynamicElements[x].m_piElement; piElement->ProcessFrame(m_vPlayMovementPos,&m_PlayArea,dwCurrentTime,dTimeFraction); } }
void CBombProjectile::ProcessFrame(unsigned int dwCurrentTime,double dTimeFraction) { CEntityBase::ProcessFrame(dwCurrentTime,dTimeFraction); m_nCurrentTime=dwCurrentTime; if(GetState()==eBombState_Normal) { if(dwCurrentTime>(m_dwCreationTime+m_pType->m_nTimeToExplode)) { if(m_pTypeBase->GetStateAnimations(eBombState_Hit)) { m_PhysicInfo.vVelocity=Origin; m_PhysicInfo.dwMoveType=PHYSIC_MOVE_TYPE_NONE; SetState(eBombState_Hit); } else { Remove(); } } } else if(GetState()==eBombState_Hit) { if(dwCurrentTime>(m_dwCreationTime+m_pType->m_nTimeToExplode+m_pType->m_nDamageEndTime)) { Remove(); } else if(dwCurrentTime>(m_dwCreationTime+m_pType->m_nTimeToExplode+m_pType->m_nDamageStartTime)) { IGenericCamera *piCamera=g_PlayAreaManagerWrapper.m_piInterface->GetCamera(); CVector vCameraPos=piCamera?piCamera->GetPosition():Origin; REL(piCamera); double dElapsedTime=((double)(dwCurrentTime-(m_dwCreationTime+m_pType->m_nTimeToExplode+m_pType->m_nDamageStartTime))); double dTotalDuration=((double)(m_pType->m_nDamageEndTime-m_pType->m_nDamageStartTime)); double dElapsedFraction=dElapsedTime/dTotalDuration; SBombDamageData data; data.dTimeFraction=dTimeFraction; data.dDamage=m_pType->m_dDamagePerSecond*dTimeFraction; data.dRadius=(m_pType->m_dDamageEndRadius-m_pType->m_dDamageStartRadius)*dElapsedFraction+m_pType->m_dDamageStartRadius; data.vCameraPos=vCameraPos; data.playAreaPlane=CPlane(AxisPosY,m_PhysicInfo.vPosition); if(dwCurrentTime>m_nNextDamageEffect) { data.bDamageEffect=true; m_nNextDamageEffect=dwCurrentTime+m_pType->m_nDamageEffectInterval; } GetEntityManager()->PerformUnaryOperation(ApplyDamageOperation,this,&data); } } }
void AABox::ComputePlanes() { CVector3 nX( 1.0f, 0.0f, 0.0f ); CVector3 nY( 0.0f, 1.0f, 0.0f ); CVector3 nZ( 0.0f, 1.0f, 0.0f ); mPlaneNX[0] = CPlane( nX, mMin.GetX() ); mPlaneNX[1] = CPlane( -nX, mMax.GetX() ); mPlaneNY[0] = CPlane( nY, mMin.GetY() ); mPlaneNY[1] = CPlane( -nY, mMax.GetY() ); mPlaneNZ[0] = CPlane( nZ, mMin.GetZ() ); mPlaneNZ[1] = CPlane( -nZ, mMax.GetZ() ); }
bool IntrCircle3Plane3<Real>::Test () { mQuantity = 0; // Construct the plane of the circle. Plane3<Real> CPlane(mCircle->Normal,mCircle->Center); // Compute the intersection of this plane with the input plane. IntrPlane3Plane3<Real> intr(*mPlane,CPlane); if (!intr.Find()) { // Planes are parallel and nonintersecting. mIntersectionType = IT_EMPTY; return false; } if (intr.GetIntersectionType() == IT_PLANE) { // Planes are the same, the circle is the common intersection set. mIntersectionType = IT_OTHER; return true; } // The planes intersect in a line. const Line3<Real>& line = intr.GetIntersectionLine(); // Locate one or two points that are on the circle and line. If the // line is t*D+P, the circle center is C, and the circle radius is r, // then r^2 = |t*D+P-C|^2 = |D|^2*t^2 + 2*Dot(D,P-C)*t + |P-C|^2. This // is a quadratic equation of the form: a2*t^2 + 2*a1*t + a0 = 0. Vector3<Real> diff = line.Origin - mCircle->Center; Real a2 = line.Direction.SquaredLength(); Real a1 = diff.Dot(line.Direction); Real a0 = diff.SquaredLength() - mCircle->Radius*mCircle->Radius; // Real-valued roots imply an intersection. Real discr = a1*a1 - a0*a2; mIntersectionType = (discr >= (Real)0 ? IT_POINT : IT_EMPTY); return mIntersectionType != IT_EMPTY; }
void CCamera::SetProjectionMatrix( const CMat4 &tmat ){ _projection=tmat; CMat4 mat=tmat.Transpose(); CVec4 l=(mat[3]+mat[0]); CVec4 r=(mat[3]-mat[0]); CVec4 b=(mat[3]+mat[1]); CVec4 t=(mat[3]-mat[1]); CVec4 n=(mat[3]+mat[2]); CVec4 f=(mat[3]-mat[2]); _frustum.planes.clear(); _frustum.planes.push_back( CPlane( l.xyz(),l.w ).Normalize() ); _frustum.planes.push_back( CPlane( r.xyz(),r.w ).Normalize() ); _frustum.planes.push_back( CPlane( b.xyz(),b.w ).Normalize() ); _frustum.planes.push_back( CPlane( t.xyz(),t.w ).Normalize() ); _frustum.planes.push_back( CPlane( n.xyz(),n.w ).Normalize() ); _frustum.planes.push_back( CPlane( f.xyz(),f.w ).Normalize() ); // for( int i=0;i<6;++i ){ // cout<<_frustum.planes[i]<<endl; // } }
CMapFileBrush *CMapFileType::ReadBrush(char *pBuffer,unsigned int *pOffset,unsigned int fileLen,double size) { std::vector<CVector> vVectors; std::vector<SMapFileVertexTextureInfo> vTextureInfo; int nPlanes=0; CPlane *pPlanes=NULL; while((*pOffset)!=(fileLen-1)) { // vector start if(pBuffer[(*pOffset)]=='(') { char *pTempBuffer=NULL; (*pOffset)++; CVector v; for(int y=0;y<3;y++) { // 3 coordinates for(int x=0;x<3;x++) { pTempBuffer=strtok(x==0 && y==0?pBuffer+*pOffset:NULL,"(, )"); if(pTempBuffer) { v.c[x]=atof(pTempBuffer); (*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1; } } // Coordinate system conversion double temp=v.c[2]; v.c[2]=-v.c[1]; v.c[1]=temp; vVectors.push_back(v); } double dTextAngle=0.0; CVector vTextScale; SMapFileVertexTextureInfo info; pTempBuffer=strtok(pBuffer+*pOffset,"(, )"); if(pTempBuffer){strcpy(info.sFileName,pTempBuffer);(*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1;} pTempBuffer=strtok(pBuffer+*pOffset,"(, )"); if(pTempBuffer){info.s=atof(pTempBuffer);(*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1;} pTempBuffer=strtok(pBuffer+*pOffset,"(, )"); if(pTempBuffer){info.t=atof(pTempBuffer);(*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1;} pTempBuffer=strtok(pBuffer+*pOffset,"(, )"); if(pTempBuffer){dTextAngle=atof(pTempBuffer);(*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1;} pTempBuffer=strtok(pBuffer+*pOffset,"(, )"); if(pTempBuffer){vTextScale.c[0]=atof(pTempBuffer);(*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1;} pTempBuffer=strtok(pBuffer+*pOffset,"(, )"); if(pTempBuffer){vTextScale.c[1]=atof(pTempBuffer);(*pOffset)=pTempBuffer-pBuffer+strlen(pTempBuffer)+1;} vTextureInfo.push_back(info); /* std::string path; path+="Textures\\"; path+=sTextureName; path+=".bmp"; CMRImage image; image.LoadFromFile(path.c_str());*/ continue; } // entity end else if(pBuffer[(*pOffset)]=='}') { (*pOffset)++; break; } (*pOffset)++; } if(vVectors.size()>=3) { nPlanes=vVectors.size()/3; pPlanes=new CPlane[nPlanes]; for(unsigned x=0;x<vVectors.size();x+=3) { CVector vectors[3]={vVectors[x],vVectors[x+1],vVectors[x+2]}; pPlanes[x/3]=CPlane(vectors[0],vectors[1],vectors[2]); CVector newPoint=((CVector)pPlanes[x/3])*(pPlanes[x/3].d+size); pPlanes[x/3].d=newPoint*(CVector)pPlanes[x/3]; } } CMapFileBrush *pBrush=new CMapFileBrush; CPolyhedron *pPolyhedron=PolyhedronFromConvexRegion(nPlanes,pPlanes); if(pPolyhedron) { for(unsigned int x=0;x<pPolyhedron->m_vPolygons.size();x++) { CPolygon *pPolygon=pPolyhedron->m_vPolygons[x]; CMapFilePolygon *pMapPolygon=new CMapFilePolygon(*pPolygon); for(int z=0;z<nPlanes;z++) { if(pMapPolygon->m_Plane==pPlanes[z]) { strcpy(pMapPolygon->m_sTextName,vTextureInfo[z].sFileName); for(unsigned int y=0;y<pMapPolygon->m_nVertexes;y++) { //CVector temp=pMapPolygon->m_Plane*pMapPolygon->m_pVertexes[y]; CVector dist=(pMapPolygon->m_pVertexes[y]-pMapPolygon->m_pVertexes[0]); pMapPolygon->m_pTextureCoords[y].c[0]=vTextureInfo[z].s+dist.c[0]; pMapPolygon->m_pTextureCoords[y].c[1]=vTextureInfo[z].t+dist.c[1]; } } } pBrush->m_vPolygons.push_back(pMapPolygon); } delete pPolyhedron; } if(pPlanes){delete [] pPlanes;} return pBrush; }
CPlane CPolygon::GetPlane() const { return CPlane(GetVertex(0), m_normal); }
bool IntrCircle3Plane3<Real>::Find () { mQuantity = 0; // Construct the plane of the circle. Plane3<Real> CPlane(mCircle->Normal,mCircle->Center); // Compute the intersection of this plane with the input plane. IntrPlane3Plane3<Real> intr(*mPlane,CPlane); if (!intr.Find()) { // Planes are parallel and nonintersecting. mIntersectionType = IT_EMPTY; return false; } if (intr.GetIntersectionType() == IT_PLANE) { // Planes are the same, the circle is the common intersection set. mIntersectionType = IT_OTHER; return true; } // The planes intersect in a line. const Line3<Real>& line = intr.GetIntersectionLine(); // Locate one or two points that are on the circle and line. If the // line is t*D+P, the circle center is C, and the circle radius is r, // then r^2 = |t*D+P-C|^2 = |D|^2*t^2 + 2*Dot(D,P-C)*t + |P-C|^2. This // is a quadratic equation of the form: a2*t^2 + 2*a1*t + a0 = 0. Vector3<Real> diff = line.Origin - mCircle->Center; Real a2 = line.Direction.SquaredLength(); Real a1 = diff.Dot(line.Direction); Real a0 = diff.SquaredLength() - mCircle->Radius*mCircle->Radius; Real discr = a1*a1 - a0*a2; if (discr < (Real)0) { // No real roots, the circle does not intersect the plane. mIntersectionType = IT_EMPTY; return false; } mIntersectionType = IT_POINT; Real inv = ((Real)1)/a2; if (discr < Math<Real>::ZERO_TOLERANCE) { // One repeated root, the circle just touches the plane. mQuantity = 1; mPoint[0] = line.Origin - (a1*inv)*line.Direction; return true; } // Two distinct, real-valued roots, the circle intersects the plane in // two points. Real root = Math<Real>::Sqrt(discr); mQuantity = 2; mPoint[0] = line.Origin - ((a1 + root)*inv)*line.Direction; mPoint[1] = line.Origin - ((a1 - root)*inv)*line.Direction; return true; }