bool PhysicsEngine::CollisionWithMapSimple(PowerBall* b, Map* map, Vector3 &normalPlane) { MaloW::Array<MeshStrip*>* temp = map->GetMesh()->GetStrips(); //int sizeMstrip = temp->size(); int sizeVertexS0 = temp->get(0)->getNrOfVerts(); Vertex* verts; //Vector3 origin = this->GetPositionVector3(); Vector3 origin = b->GetTempPosition(); Vector3 dir = b->GetVelocity(); Vector3 dirN = dir/dir.GetLength(); verts = temp->get(0)->getVerts(); /* for(int i = 0;i<sizeMstrip;i++) { } */ Vector3 p0,p1,p2, normal, v1,v2; float smalestTime = -1; bool firstHit = false; float u, v,t; float lengthProjN = 0; Vector3 p0Store, p1Store,p2Store, normalStore; Vector3 pos = Vector3(map->GetMesh()->GetPosition()); Vector3 posS = b->GetTempPosition();//this->GetPositionVector3(); Vector3 rayDirection; Vector3 scalingMesh = map->GetMesh()->GetScaling(); D3DXMATRIX quat; D3DXMatrixRotationQuaternion(&quat, &map->GetMesh()->GetRotation()); Matrix4 rotate(quat); rotate.TransposeThis(); Matrix4 scaling; scaling.SetScale(scalingMesh); Matrix4 translate; translate.SetTranslate(pos); Matrix4 world = translate*rotate*scaling; for(int i =0; i< sizeVertexS0; i+=3) { /* p0 = Vector3(verts[i].pos).GetComponentMultiplication(scalingMesh) + pos; p1 = Vector3(verts[i+1].pos).GetComponentMultiplication(scalingMesh) +pos; p2 = Vector3(verts[i+2].pos).GetComponentMultiplication(scalingMesh) + pos; */ p0 = world*Vector3(verts[i].pos); p1 = world*Vector3(verts[i+1].pos); p2 = world*Vector3(verts[i+2].pos); v1 = p1-p0; v2 = p2-p0; rayDirection = v1.GetCrossProduct(v2); rayDirection.normalize(); float tempLength; Vector3 ny; Vector3 projN; if(RayTriIntersect(origin , rayDirection, p0, p1, p2, u, v, t) ) { normal = rayDirection; ny = origin - p0; projN = normal*ny.GetDotProduct(normal); tempLength = projN.GetLength(); if(!firstHit) { firstHit = true; smalestTime = t; lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normal; } else { if( tempLength < lengthProjN ) { smalestTime = t; lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normal; } } } // check agains all edges Vector3 lineDirection; float scalarProj; Vector3 projOnLine; Vector3 normalToLine; // edge 1: ny = origin - p0; lineDirection = p1 - p0; scalarProj = (ny.GetDotProduct(lineDirection)/lineDirection.GetLengthSquared()); projOnLine = lineDirection * scalarProj; if( (scalarProj >= 0.0f) && (scalarProj <= 1) ) { normalToLine = ny - projOnLine; tempLength = normalToLine.GetLength(); if(!firstHit) { firstHit = true; lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normalToLine; normalStore.normalize(); } else { if( tempLength < lengthProjN ) { lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normalToLine; normalStore.normalize(); } } } // edge 2: ny = origin - p1; lineDirection = p2 - p1; scalarProj = (ny.GetDotProduct(lineDirection)/lineDirection.GetLengthSquared()); projOnLine = lineDirection * scalarProj; if( (scalarProj >= 0.0f) && (scalarProj <= 1) ) { normalToLine = ny - projOnLine; tempLength = normalToLine.GetLength(); if(!firstHit) { firstHit = true; lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normalToLine; normalStore.normalize(); } else { if( tempLength < lengthProjN ) { lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normalToLine; normalStore.normalize(); } } } // edge 3: ny = origin - p2; lineDirection = p0 - p2; scalarProj = (ny.GetDotProduct(lineDirection)/lineDirection.GetLengthSquared()); projOnLine = lineDirection * scalarProj; if( (scalarProj >= 0.0f) && (scalarProj <= 1) ) { normalToLine = ny - projOnLine; tempLength = normalToLine.GetLength(); if(!firstHit) { firstHit = true; lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normalToLine; normalStore.normalize(); } else { if( tempLength < lengthProjN ) { lengthProjN = tempLength; p0Store = p0; p1Store = p1; p2Store = p2; normalStore = normal; } } } } if(firstHit) { // for checking if the ball are in the air not turned on at the moment, float eps = 0.5f; //0.001 if( (lengthProjN < (b->GetRadius() + eps)) && (lengthProjN > (b->GetRadius() - eps)) ) { b->SetNormalContact(normalStore); b->SetHasContact(true); } else { b->SetNormalContact(normalStore); b->SetHasContact(false); } if( lengthProjN <= b->GetRadius()) { Vector3 velNorm = b->GetVelocity(); velNorm.normalize(); if(normalStore.GetDotProduct(velNorm) >=0) return false; float diff = abs(lengthProjN- b->GetRadius()); //Vector3 newPo = origin -dirN*diff; //Vector3 projVel = normalStore * this->mVelocity.GetDotProduct(normalStore); Vector3 newPo = origin + normalStore*diff; /* if( projVel.GetDotProduct(normalStore) < 0.0f) { newPo = origin - normalStore*diff; return false; } else newPo = origin + normalStore*diff; */ //this->SetPosition(newPo); b->SetTempPosition(newPo); normalPlane = normalStore; //this->mNormalContact = normalPlane; //this->mHasContact = true; return true; } else { normalPlane = Vector3(0,0,0); //this->mNormalContact = normalPlane; //this->mHasContact = false; return false; } } normalPlane = Vector3(0,0,0); b->SetNormalContact(normalPlane); //this->mHasContact = false; return false; }
void Map::Update(const float dt) { if(this->mIsRotating) { float angle; float speed = PI/26.0f; if(this->mTargetAngleX <0) angle = -speed*dt*0.001f; else angle = speed*dt*0.001f; Matrix3 temp; temp.SetRotationZ(this->mAngleZ); Vector3 xA = Vector3(1,0,0); Vector3 xAnew = temp * xA; this->mAngleX += angle; this->mMesh->RotateAxis(xAnew.GetD3DVec(), angle); if(this->mTargetAngleZ <0) angle = -speed*dt*0.001f; else angle = speed*dt*0.001f; this->mAngleZ += angle; this->mMesh->RotateAxis(D3DXVECTOR3(0,0,1), angle); } if(this->mMeshHotZone) { Vector3 scalingMesh = this->mMesh->GetScaling(); Vector3 pos = this->mMesh->GetPosition(); D3DXMATRIX quat; D3DXMatrixRotationQuaternion(&quat, &this->mMesh->GetRotation()); Matrix4 rotate(quat); rotate.TransposeThis(); Matrix4 scaling; scaling.SetScale(scalingMesh); Matrix4 translate; translate.SetTranslate(pos); Matrix4 rotateY; rotateY.SetRotationY(dt*0.001f*(PI/2.0f)); Matrix4 newRotate = rotateY*rotate; Matrix4 world = translate*rotate*scaling; Vector3 posHotZone = Vector3(13.5f,2.5,13.5f); Vector3 newPos4HotZoneMesh = world * posHotZone; Vector4 newYrot = rotate*Vector4(0,1,0,0); Vector3 newYrot2 = Vector3(newYrot.x, newYrot.y, newYrot.z); D3DXQUATERNION q = this->mMesh->GetRotation(); this->mMeshHotZone->SetQuaternion(this->mMesh->GetRotation()); this->mAngleY += dt*0.001f*(PI/2.0f); this->mMeshHotZone->SetQuaternion(q); this->mMeshHotZone->SetPosition(newPos4HotZoneMesh.GetD3DVec()); this->mMeshHotZone->RotateAxis(newYrot2.GetD3DVec(), this->mAngleY); Vector3 hotPos = Vector3(13.5f,4.5,13.5f); Vector3 newHotPos = world * hotPos; /* test to see that the flag mesh is not straight and thats true. */ //this->mMeshHotZone->RotateAxis(D3DXVECTOR3(0,1,0), dt*0.001f*(PI/2.0f)); this->mHotZonePosition = newHotPos; } float newdt = dt * 0.001f; float fraction = 1.0f - this->mShrink * newdt; this->mMesh->Scale(D3DXVECTOR3(fraction,1,fraction)); this->mScaledRadius *= fraction;//this->mScaledRadius/this->mRadius; }
//--------------------------------- // //--------------------------------- void Matrix4::Scale(const Vector3& scale) { Matrix4 scaleMatrix; scaleMatrix.SetScale( scale ); *this *= scaleMatrix; }