bool RayIntersectorKDTreeNode::FindBestSplit(const Vector<UINT> &TriangleIndices, const RayIntersectorKDTree &Root, UINT &Axis, float &SplitValue) const { Rectangle3f BBox = ComputeBBox(TriangleIndices, Root); int BestAxis = -1; UINT BestChildImprovement = 8; for(UINT CurAxis = 0; CurAxis < 3; CurAxis++) { UINT LeftCount, RightCount; TestSplit(TriangleIndices, Root, CurAxis, BBox, LeftCount, RightCount); /*const UINT BestChildCost = TriangleIndices.Length(); const UINT WorstChildCost = TriangleIndices.Length() * 2; const UINT ActualChildCost = LeftCount + RightCount; const float CurAxisValue = float(ActualChildCost) / float(WorstChildCost);*/ const UINT CurChildImprovement = Math::Min(TriangleIndices.Length() - LeftCount, TriangleIndices.Length() - RightCount); if(CurChildImprovement > BestChildImprovement && LeftCount > 0 && RightCount > 0) { BestAxis = CurAxis; BestChildImprovement = CurChildImprovement; } } if(BestAxis == -1) { return false; } else { Axis = BestAxis; SplitValue = BBox.Center()[Axis]; return true; } }
void CRigidBody::HandlePushCollision(CCollisionMessage* ColMsg) { CVehicle* Car = (CVehicle*)ColMsg->GetEntity(); CLog::GetLog().Write(LOG_MISC, "In HandlePushCollision()"); /***************** First, findout how hard Car was hit **************/ float force = ColMsg->GetPushForce()->Length(); //CLog::GetLog().Write(LOG_MISC, "force = %f", force); Vector3f Direction = (*ColMsg->GetNormal())*force; CLog::GetLog().Write(LOG_MISC, "\n\n\nforce = %f", force); CLog::GetLog().Write(LOG_MISC, "Direction = (%f, %f, %f)", Direction.X(), Direction.Y(), Direction.Z()); /***************** Next, findout where along body Car was hit *********/ float where; Rectangle3f Rect = *ColMsg->GetPlane(); Vector3f ColPoint = *ColMsg->GetColPoint(); Plane3f P1 = Plane3f(Rect.Edge0(), Rect.Origin()); where = P1.DistanceTo(ColPoint)/Rect.Edge0().Length(); // So where = [1,0]. 0 - at origin, 1 - opposite origin }
void MeshDistanceBruteForce::InitMeshList(const Vector< pair<const BaseMesh*, Matrix4> > &meshes) { UINT triangleSum = 0; const UINT meshCount = meshes.Length(); for(UINT meshIndex = 0; meshIndex < meshCount; meshIndex++) { triangleSum += meshes[meshIndex].first->FaceCount(); } _triangles.Allocate(triangleSum); UINT triangleListIndex = 0; for(UINT meshIndex = 0; meshIndex < meshCount; meshIndex++) { const BaseMesh &curMesh = *meshes[meshIndex].first; const Matrix4 &curTransform = meshes[meshIndex].second; const UINT triangleCount = curMesh.FaceCount(); const MeshVertex *vertices = curMesh.Vertices(); const DWORD *indices = curMesh.Indices(); for(UINT triangleIndex = 0; triangleIndex < triangleCount; triangleIndex++) { TriangleEntry &curEntry = _triangles[triangleListIndex]; curEntry.V[0] = curTransform.TransformPoint(vertices[ indices[ triangleIndex * 3 + 0 ] ].Pos); curEntry.V[1] = curTransform.TransformPoint(vertices[ indices[ triangleIndex * 3 + 1 ] ].Pos); curEntry.V[2] = curTransform.TransformPoint(vertices[ indices[ triangleIndex * 3 + 2 ] ].Pos); Rectangle3f curBBox = Rectangle3f::ConstructFromTwoPoints(curEntry.V[0], curEntry.V[1]); curBBox.ExpandBoundingBox(curEntry.V[2]); curEntry.center = curBBox.Center(); curEntry.variance = curBBox.Variance(); triangleListIndex++; } } }
void Indicator::RenderBox(GraphicsDevice &GD, MatrixController &MC, float Radius, const Rectangle3f &Rect, RGBColor Color) { RenderCylinder(GD, MC, Radius, Vec3f(Rect.Min.x, Rect.Min.y, Rect.Min.z), Vec3f(Rect.Max.x, Rect.Min.y, Rect.Min.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Max.x, Rect.Min.y, Rect.Min.z), Vec3f(Rect.Max.x, Rect.Max.y, Rect.Min.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Max.x, Rect.Max.y, Rect.Min.z), Vec3f(Rect.Min.x, Rect.Max.y, Rect.Min.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Min.x, Rect.Max.y, Rect.Min.z), Vec3f(Rect.Min.x, Rect.Min.y, Rect.Min.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Min.x, Rect.Min.y, Rect.Min.z), Vec3f(Rect.Min.x, Rect.Min.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Max.x, Rect.Min.y, Rect.Min.z), Vec3f(Rect.Max.x, Rect.Min.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Max.x, Rect.Max.y, Rect.Min.z), Vec3f(Rect.Max.x, Rect.Max.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Min.x, Rect.Max.y, Rect.Min.z), Vec3f(Rect.Min.x, Rect.Max.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Min.x, Rect.Min.y, Rect.Max.z), Vec3f(Rect.Max.x, Rect.Min.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Max.x, Rect.Min.y, Rect.Max.z), Vec3f(Rect.Max.x, Rect.Max.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Max.x, Rect.Max.y, Rect.Max.z), Vec3f(Rect.Min.x, Rect.Max.y, Rect.Max.z), Color); RenderCylinder(GD, MC, Radius, Vec3f(Rect.Min.x, Rect.Max.y, Rect.Max.z), Vec3f(Rect.Min.x, Rect.Min.y, Rect.Max.z), Color); Matrix4 Scale = Matrix4::Scaling(Rect.Dimensions()); Matrix4 Translate = Matrix4::Translation(Rect.Min); MC.World = Scale * Translate; LPDIRECT3DDEVICE9 Device = GD.CastD3D9().GetDevice(); D3DCOLOR D3DColor = RGBColor(90, 90, 90); Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVBLENDFACTOR); Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); Device->SetRenderState(D3DRS_BLENDFACTOR, D3DColor); _Box.SetColor(Color); _Box.Render(); Device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); }
void RayIntersectorKDTreeNode::TestSplit(const Vector<UINT> &TriangleIndices, const RayIntersectorKDTree &Root, UINT Axis, const Rectangle3f &BBox, UINT &LeftCount, UINT &RightCount) const { float SplitPoint = BBox.Center()[Axis]; LeftCount = 0; RightCount = 0; for(UINT TriangleIndex = 0; TriangleIndex < TriangleIndices.Length(); TriangleIndex++) { UINT LeftVertices = 0, RightVertices = 0; const UINT BaseIndexIndex = TriangleIndices[TriangleIndex] * 3; for(UINT VertexIndex = 0; VertexIndex < 3; VertexIndex++) { const Vec3f &CurVertex = Root._Vertices[Root._Indices[BaseIndexIndex + VertexIndex]]; if(CurVertex[Axis] < SplitPoint) { LeftVertices++; } if(CurVertex[Axis] >= SplitPoint) { RightVertices++; } } bool OnLeftSide = (LeftVertices > RightVertices); bool OnRightSide = !OnLeftSide; if(OnLeftSide) { LeftCount++; } if(OnRightSide) { RightCount++; } } }
bool Math::RayIntersectRectangle(const Ray3D &Ray, const Rectangle3f &Rect) { for(UINT PlaneIndex = 0; PlaneIndex < 6; PlaneIndex++) { Vec3f Pt; UINT Axis; if(PlaneIndex < 3) { Pt = Rect.Min; Axis = PlaneIndex; } else { Pt = Rect.Max; Axis = PlaneIndex - 3; } const float t = (Pt[Axis] - Ray.P0[Axis]) / Ray.D[Axis]; const Vec3f IntersectPt = Ray.P0 + Ray.D * t; if(Rect.PtWithinDistance(IntersectPt, 1e-4f)) { return true; } } return false; }
bool MeshDistanceBruteForce::IntersectMeshList(const Vector< pair<const BaseMesh*, Matrix4> > &meshes) const { const UINT meshCount = meshes.Length(); const UINT mTriangleCount = _triangles.Length(); for(UINT meshIndex = 0; meshIndex < meshCount; meshIndex++) { const BaseMesh &curMesh = *meshes[meshIndex].first; const Matrix4 &curTransform = meshes[meshIndex].second; const UINT triangleCount = curMesh.FaceCount(); const MeshVertex *vertices = curMesh.Vertices(); const DWORD *indices = curMesh.Indices(); for(UINT outerTriangleIndex = 0; outerTriangleIndex < triangleCount; outerTriangleIndex++) { const Vec3f t0 = curTransform.TransformPoint(vertices[ indices[ outerTriangleIndex * 3 + 0 ] ].Pos); const Vec3f t1 = curTransform.TransformPoint(vertices[ indices[ outerTriangleIndex * 3 + 1 ] ].Pos); const Vec3f t2 = curTransform.TransformPoint(vertices[ indices[ outerTriangleIndex * 3 + 2 ] ].Pos); Rectangle3f curBBox = Rectangle3f::ConstructFromTwoPoints(t0, t1); curBBox.ExpandBoundingBox(t2); const Vec3f center = curBBox.Center(); const Vec3f variance = curBBox.Variance(); for(UINT innerTriangleIndex = 0; innerTriangleIndex < mTriangleCount; innerTriangleIndex++) { const TriangleEntry &curEntry = _triangles[innerTriangleIndex]; if(Math::Abs(center.x - curEntry.center.x) <= variance.x + curEntry.variance.x && Math::Abs(center.y - curEntry.center.y) <= variance.y + curEntry.variance.y && Math::Abs(center.z - curEntry.center.z) <= variance.z + curEntry.variance.z) { if(Math::DistanceTriangleTriangleSq(t0, t1, t2, curEntry.V[0], curEntry.V[1], curEntry.V[2]) == 0.0f) { float value = Math::DistanceTriangleTriangleSq(t0, t1, t2, curEntry.V[0], curEntry.V[1], curEntry.V[2]); return true; } } } } } return false; }
void BaseMesh::CreateBox(const Rectangle3f &Rect) { Vec3f Dimensions = Rect.Dimensions(); CreateBox(Dimensions.x, Dimensions.y, Dimensions.z, 0); Translate(Rect.Center()); }