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);
}
Beispiel #2
0
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;
	}
}
Beispiel #3
0
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);
}