void FKSphylElem::DrawElemWire(class FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, const FVector& Scale3D, const FColor Color) const { const FVector Scale3DAbs = Scale3D.GetAbs(); const float ScaleRadius = FMath::Max(Scale3DAbs.X, Scale3DAbs.Y); const float ScaleLength = Scale3DAbs.Z; FVector Origin = ElemTM.GetLocation(); FVector XAxis = ElemTM.GetScaledAxis(EAxis::X); FVector YAxis = ElemTM.GetScaledAxis(EAxis::Y); FVector ZAxis = ElemTM.GetScaledAxis(EAxis::Z); // Draw top and bottom circles FVector TopEnd = Origin + ScaleLength*0.5f*Length*ZAxis; FVector BottomEnd = Origin - ScaleLength*0.5f*Length*ZAxis; DrawCircle(PDI, TopEnd, XAxis, YAxis, Color, ScaleRadius*Radius, DrawCollisionSides, SDPG_World); DrawCircle(PDI, BottomEnd, XAxis, YAxis, Color, ScaleRadius*Radius, DrawCollisionSides, SDPG_World); // Draw domed caps DrawHalfCircle(PDI, TopEnd, YAxis, ZAxis, Color, ScaleRadius* Radius); DrawHalfCircle(PDI, TopEnd, XAxis, ZAxis, Color, ScaleRadius*Radius); FVector NegZAxis = -ZAxis; DrawHalfCircle(PDI, BottomEnd, YAxis, NegZAxis, Color, ScaleRadius*Radius); DrawHalfCircle(PDI, BottomEnd, XAxis, NegZAxis, Color, ScaleRadius*Radius); // Draw connecty lines PDI->DrawLine(TopEnd + ScaleRadius*Radius*XAxis, BottomEnd + ScaleRadius*Radius*XAxis, Color, SDPG_World); PDI->DrawLine(TopEnd - ScaleRadius*Radius*XAxis, BottomEnd - ScaleRadius*Radius*XAxis, Color, SDPG_World); PDI->DrawLine(TopEnd + ScaleRadius*Radius*YAxis, BottomEnd + ScaleRadius*Radius*YAxis, Color, SDPG_World); PDI->DrawLine(TopEnd - ScaleRadius*Radius*YAxis, BottomEnd - ScaleRadius*Radius*YAxis, Color, SDPG_World); }
void SetupNonUniformHelper(FVector& Scale3D, float& MinScale, float& MinScaleAbs, FVector& Scale3DAbs) { // if almost zero, set min scale // @todo fixme if (Scale3D.IsNearlyZero()) { // set min scale Scale3D = FVector(0.1f); } Scale3DAbs = Scale3D.GetAbs(); MinScaleAbs = Scale3DAbs.GetMin(); MinScale = FMath::Max3(Scale3D.X, Scale3D.Y, Scale3D.Z) < 0.f ? -MinScaleAbs : MinScaleAbs; //if all three values are negative make minScale negative if (FMath::IsNearlyZero(MinScale)) { // only one of them can be 0, we make sure they have mini set up correctly MinScale = 0.1f; MinScaleAbs = 0.1f; } }
bool FSeparatingAxisPointCheck::TestSeparatingAxisCommon(const FVector& Axis, float ProjectedPolyMin, float ProjectedPolyMax) { const float ProjectedCenter = FVector::DotProduct(Axis, BoxCenter); const float ProjectedExtent = FVector::DotProduct(Axis.GetAbs(), BoxExtent); const float ProjectedBoxMin = ProjectedCenter - ProjectedExtent; const float ProjectedBoxMax = ProjectedCenter + ProjectedExtent; if (ProjectedPolyMin > ProjectedBoxMax || ProjectedPolyMax < ProjectedBoxMin) { return false; } if (bCalcLeastPenetration) { const float AxisMagnitudeSqr = Axis.SizeSquared(); if (AxisMagnitudeSqr > (SMALL_NUMBER * SMALL_NUMBER)) { const float InvAxisMagnitude = FMath::InvSqrt(AxisMagnitudeSqr); const float MinPenetrationDist = (ProjectedBoxMax - ProjectedPolyMin) * InvAxisMagnitude; const float MaxPenetrationDist = (ProjectedPolyMax - ProjectedBoxMin) * InvAxisMagnitude; if (MinPenetrationDist < BestDist) { BestDist = MinPenetrationDist; HitNormal = -Axis * InvAxisMagnitude; } if (MaxPenetrationDist < BestDist) { BestDist = MaxPenetrationDist; HitNormal = Axis * InvAxisMagnitude; } } } return true; }
void FKSphylElem::DrawElemSolid(FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, const FVector& Scale3D, const FMaterialRenderProxy* MaterialRenderProxy) const { const FVector Scale3DAbs = Scale3D.GetAbs(); const float ScaleRadius = FMath::Max(Scale3DAbs.X, Scale3DAbs.Y); const float ScaleLength = Scale3DAbs.Z; const int32 NumSides = DrawCollisionSides; const int32 NumRings = (DrawCollisionSides / 2) + 1; // The first/last arc are on top of each other. const int32 NumVerts = (NumSides + 1) * (NumRings + 1); FDynamicMeshVertex* Verts = (FDynamicMeshVertex*)FMemory::Malloc(NumVerts * sizeof(FDynamicMeshVertex)); // Calculate verts for one arc FDynamicMeshVertex* ArcVerts = (FDynamicMeshVertex*)FMemory::Malloc((NumRings + 1) * sizeof(FDynamicMeshVertex)); for (int32 RingIdx = 0; RingIdx < NumRings + 1; RingIdx++) { FDynamicMeshVertex* ArcVert = &ArcVerts[RingIdx]; float Angle; float ZOffset; if (RingIdx <= DrawCollisionSides / 4) { Angle = ((float)RingIdx / (NumRings - 1)) * PI; ZOffset = 0.5 * ScaleLength * Length; } else { Angle = ((float)(RingIdx - 1) / (NumRings - 1)) * PI; ZOffset = -0.5 * ScaleLength * Length; } // Note- unit sphere, so position always has mag of one. We can just use it for normal! FVector SpherePos; SpherePos.X = 0.0f; SpherePos.Y = ScaleRadius * Radius * FMath::Sin(Angle); SpherePos.Z = ScaleRadius * Radius * FMath::Cos(Angle); ArcVert->Position = SpherePos + FVector(0, 0, ZOffset); ArcVert->SetTangents( FVector(1, 0, 0), FVector(0.0f, -SpherePos.Z, SpherePos.Y), SpherePos ); ArcVert->TextureCoordinate.X = 0.0f; ArcVert->TextureCoordinate.Y = ((float)RingIdx / NumRings); } // Then rotate this arc NumSides+1 times. for (int32 SideIdx = 0; SideIdx < NumSides + 1; SideIdx++) { const FRotator ArcRotator(0, 360.f * ((float)SideIdx / NumSides), 0); const FRotationMatrix ArcRot(ArcRotator); const float XTexCoord = ((float)SideIdx / NumSides); for (int32 VertIdx = 0; VertIdx < NumRings + 1; VertIdx++) { int32 VIx = (NumRings + 1)*SideIdx + VertIdx; Verts[VIx].Position = ArcRot.TransformPosition(ArcVerts[VertIdx].Position); Verts[VIx].SetTangents( ArcRot.TransformVector(ArcVerts[VertIdx].TangentX), ArcRot.TransformVector(ArcVerts[VertIdx].GetTangentY()), ArcRot.TransformVector(ArcVerts[VertIdx].TangentZ) ); Verts[VIx].TextureCoordinate.X = XTexCoord; Verts[VIx].TextureCoordinate.Y = ArcVerts[VertIdx].TextureCoordinate.Y; } } FDynamicMeshBuilder MeshBuilder; { // Add all of the vertices to the mesh. for (int32 VertIdx = 0; VertIdx < NumVerts; VertIdx++) { MeshBuilder.AddVertex(Verts[VertIdx]); } // Add all of the triangles to the mesh. for (int32 SideIdx = 0; SideIdx < NumSides; SideIdx++) { const int32 a0start = (SideIdx + 0) * (NumRings + 1); const int32 a1start = (SideIdx + 1) * (NumRings + 1); for (int32 RingIdx = 0; RingIdx < NumRings; RingIdx++) { MeshBuilder.AddTriangle(a0start + RingIdx + 0, a1start + RingIdx + 0, a0start + RingIdx + 1); MeshBuilder.AddTriangle(a1start + RingIdx + 0, a1start + RingIdx + 1, a0start + RingIdx + 1); } } } MeshBuilder.Draw(PDI, ElemTM.ToMatrixWithScale(), MaterialRenderProxy, SDPG_World,0.f); FMemory::Free(Verts); FMemory::Free(ArcVerts); }