Example #1
0
void DrawWireShape(NxShape *shape, const NxVec3& color)
{
    switch(shape->getType())
    {
		case NX_SHAPE_PLANE:
			DrawWirePlane(shape, color);
		break;
		case NX_SHAPE_BOX:
			DrawWireBox(shape, color);
		break;
		case NX_SHAPE_SPHERE:
			DrawWireSphere(shape, color);
		break;
		case NX_SHAPE_CAPSULE:
			DrawWireCapsule(shape, color);
		break;
		case NX_SHAPE_CONVEX:
			DrawWireConvex(shape, color);
		break;		
		case NX_SHAPE_MESH:
			DrawWireMesh(shape, color);
		break;
		default:
		break;
	}
}
void FSpringComponentVisualizer::DrawVisualization( const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI )
{
	if (const UPhysicsSpringComponent* SpringComp = Cast<const UPhysicsSpringComponent>(Component))
	{
		//interpolate color by compression
		const float CompressionNormalized = SpringComp->GetNormalizedCompressionScalar();
		float R = FMath::Lerp(RestColor.R, CompressedColor.R, CompressionNormalized);
		float G = FMath::Lerp(RestColor.G, CompressedColor.G, CompressionNormalized);
		float B = FMath::Lerp(RestColor.B, CompressedColor.B, CompressionNormalized);
		const FColor CurrentColor = SpringComp->bIsActive ? FColor(R, G, B) : DisabledColor;
		
		//draw capsule for spring sweep
		const FTransform& WorldTM = SpringComp->GetComponentToWorld();
		const FVector SpringStart = WorldTM.GetLocation();
		const FVector SpringEnd = SpringComp->GetSpringCurrentEndPoint();
		const float HalfHeight = (SpringEnd - SpringStart).Size() * 0.5f + SpringComp->SpringRadius;
		DrawWireCapsule(PDI, FMath::Lerp(SpringStart, SpringEnd, 0.5f), WorldTM.GetUnitAxis(EAxis::Z), WorldTM.GetUnitAxis(EAxis::Y), WorldTM.GetUnitAxis(EAxis::X), CurrentColor, SpringComp->SpringRadius, HalfHeight, 25, SDPG_World);
	}
}
		virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override
		{
			QUICK_SCOPE_CYCLE_COUNTER( STAT_GetDynamicMeshElements_DrawDynamicElements );

		
			const FMatrix& LocalToWorld = GetLocalToWorld();
			const int32 CapsuleSides =  FMath::Clamp<int32>(CapsuleRadius/4.f, 16, 64);

			for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
			{

				if (VisibilityMap & (1 << ViewIndex))
				{
					const FSceneView* View = Views[ViewIndex];
					const FLinearColor DrawCapsuleColor = GetViewSelectionColor(ShapeColor, *View, IsSelected(), IsHovered(), false, IsIndividuallySelected() );

					FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex);
					DrawWireCapsule( PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetScaledAxis( EAxis::X ), LocalToWorld.GetScaledAxis( EAxis::Y ), LocalToWorld.GetScaledAxis( EAxis::Z ), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World );
				}
			}
		}
Example #4
0
void Update()
{
	NxMat34 mat34;
	NxMat33 mat;
	NxQuat quat(0.0f,NxVec3(0,1,0));  
	mat.fromQuat(quat);
	NxBox worldBox;
	worldBox.extents	= NxVec3(2, 2, 2);
	worldBox.rot		= mat;

	NxSphere	worldSphere;
	NxBounds3	worldBounds;
	NxCapsule	worldCapsule;
	worldCapsule.radius = 2.0f;

	NxU32 nbPlanes = 2;
	NxPlane worldPlanes[2];
	worldPlanes[0].set(NxVec3(-2,0,2), NxVec3(0,0,1));
	worldPlanes[1].set(NxVec3(-2,0,2), NxVec3(1,0,0));

	NxU32 nbDynamicShapes	= gScene->getNbDynamicShapes();
	NxU32 nbStaticShapes	= gScene->getNbStaticShapes();
	NxU32 nbShapes = 0;
	NxShapesType type;

	int i = 0;
	for (i = 0; i < 3; ++ i)
	{
		if (i == 0)
		{
			nbShapes = nbDynamicShapes;
			type	 = NX_DYNAMIC_SHAPES;
			switch(gOverlapType)
			{
			case OVERLAP_AABB:
			case OVERLAP_CHECK_AABB:
				worldBounds.set(gMIN, gMAX);
				break;
			case OVERLAP_OBB:
			case OVERLAP_CHECK_OBB:
				worldBox.center = gBoxCenter;
				break;
			case OVERLAP_CAPSULE:
			case OVERLAP_CHECK_CAPSULE:
				worldCapsule = NxCapsule(gCapsuleSegment, gCapsuleRadius);
				break;
			case OVERLAP_SPHERE:
			case OVERLAP_CHECK_SPHERE:
				worldSphere = NxSphere(gSphereCenter, gSphereRadius);
				break;
			}
		}
		else if (i == 1)
		{
			nbShapes = nbStaticShapes;
			type	 = NX_STATIC_SHAPES;
			switch(gOverlapType)
			{
			case OVERLAP_AABB:
			case OVERLAP_CHECK_AABB:
				worldBounds.set(gMIN+NxVec3(-6.0f,0,0),gMAX+NxVec3(-6.0f,0,0));
				break;
			case OVERLAP_OBB:
			case OVERLAP_CHECK_OBB:
				worldBox.center = gBoxCenter+NxVec3(-6,0,0);
				break;
			case OVERLAP_CAPSULE:
			case OVERLAP_CHECK_CAPSULE:
				worldCapsule.p0.x = gCapsuleSegment.p0.x - 6.0f;
				worldCapsule.p1.x = gCapsuleSegment.p1.x - 6.0f;
				break;
			case OVERLAP_SPHERE:
			case OVERLAP_CHECK_SPHERE:
				worldSphere = NxSphere(gSphereCenter + NxVec3(-6,0,0), gSphereRadius);
				break;
			}
		}
		else if (i == 2)
		{
			nbShapes = nbStaticShapes + nbDynamicShapes;
			type	 = NX_ALL_SHAPES;
			switch(gOverlapType)
			{
			case OVERLAP_AABB:
			case OVERLAP_CHECK_AABB:
				worldBounds.set(gMIN+NxVec3(6.0f,0,0),gMAX+NxVec3(6.0f,0,0));
				break;
			case OVERLAP_OBB:
			case OVERLAP_CHECK_OBB:
				worldBox.center = gBoxCenter+NxVec3(6,0,0);
				break;
			case OVERLAP_CAPSULE:
			case OVERLAP_CHECK_CAPSULE:
				worldCapsule.p0.x = gCapsuleSegment.p0.x + 6.0f;
				worldCapsule.p1.x = gCapsuleSegment.p1.x + 6.0f;
				break;
			case OVERLAP_SPHERE:
			case OVERLAP_CHECK_SPHERE:
				worldSphere = NxSphere(gSphereCenter + NxVec3(6,0,0), gSphereRadius);
				break;
			}
		}

		NxShape** shapes = (NxShape**)NxAlloca(nbShapes*sizeof(NxShape*));
		for (NxU32 j = 0; j < nbShapes; j++)  shapes[j] = NULL;
		NxU32 activeGroups = 0xffffffff;
		NxGroupsMask* groupsMask = NULL;
		bool bResult	= true;
		float linewidth = 1.0f;
		switch(gOverlapType)
		{
		case OVERLAP_AABB:
			gScene->overlapAABBShapes(worldBounds, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask, true);
			NxCreateBox(worldBox, worldBounds, mat34);
			DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			break;
		case OVERLAP_CHECK_AABB:
			bResult = gScene->checkOverlapAABB(worldBounds, type, activeGroups, groupsMask);
			NxCreateBox(worldBox, worldBounds, mat34);
			if (bResult == true)
				DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			else
				DrawWireBox(worldBox, NxVec3(0,1,0), linewidth);
			break;
		case OVERLAP_OBB:
			gScene->overlapOBBShapes(worldBox, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			break;
		case OVERLAP_CHECK_OBB:
			if (gScene->checkOverlapOBB(worldBox, type, activeGroups, groupsMask) == true)
				DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			else
				DrawWireBox(worldBox, NxVec3(0,1,0), linewidth);
			break;
		case OVERLAP_CAPSULE:
			gScene->overlapCapsuleShapes(worldCapsule, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawWireCapsule(worldCapsule, NxVec3(1,0,0));
			break;
		case OVERLAP_CHECK_CAPSULE:
			if (gScene->checkOverlapCapsule(worldCapsule, type,activeGroups, groupsMask) == true)
				DrawWireCapsule(worldCapsule, NxVec3(1,0,0));
			else
				DrawWireCapsule(worldCapsule, NxVec3(0,1,0));
			break;
		case OVERLAP_SPHERE:
			gScene->overlapSphereShapes(worldSphere, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawWireSphere(&worldSphere, NxVec3(1,0,0));
			break;
		case OVERLAP_CHECK_SPHERE:
			if (gScene->checkOverlapSphere(worldSphere, type,activeGroups, groupsMask) == true)
				DrawWireSphere(&worldSphere, NxVec3(1,0,0));
			else
				DrawWireSphere(&worldSphere, NxVec3(0,1,0));
			break;
		case OVERLAP_CULL:
			gScene->cullShapes(nbPlanes, worldPlanes, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawLine(NxVec3(-20,0,2), NxVec3(-2,0,2),NxVec3(1,0,0), linewidth);
			DrawLine(NxVec3(-2,0,-20), NxVec3(-2,0,2),NxVec3(1,0,0), linewidth);
			break;
		}
	}
}
void FDebugRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const 
{
	QUICK_SCOPE_CYCLE_COUNTER( STAT_DebugRenderSceneProxy_GetDynamicMeshElements );

	// Draw solid spheres
	struct FMaterialCache
	{
		FMaterialCache() : bUseFakeLight(false) {}

		FMaterialRenderProxy* operator[](FLinearColor Color)
		{
			FMaterialRenderProxy* MeshColor = NULL;
			const uint32 HashKey = GetTypeHash(Color);
			if (MeshColorInstances.Contains(HashKey))
			{
				MeshColor = *MeshColorInstances.Find(HashKey);
			}
			else
			{
				if (bUseFakeLight && SolidMeshMaterial.IsValid())
				{
					
					MeshColor = new(FMemStack::Get())  FColoredMaterialRenderProxy(
						SolidMeshMaterial->GetRenderProxy(false, false),
						Color,
						"GizmoColor"
						);
				}
				else
				{
					MeshColor = new(FMemStack::Get()) FColoredMaterialRenderProxy(GEngine->DebugMeshMaterial->GetRenderProxy(false, false), Color);
				}

				MeshColorInstances.Add(HashKey, MeshColor);
			}

			return MeshColor;
		}

		void UseFakeLight(bool UseLight, class UMaterial* InMaterial) { bUseFakeLight = UseLight; SolidMeshMaterial = InMaterial; }

		TMap<uint32, FMaterialRenderProxy*> MeshColorInstances;
		TWeakObjectPtr<class UMaterial> SolidMeshMaterial;
		bool bUseFakeLight;
	};

	FMaterialCache MaterialCache[2];
	MaterialCache[1].UseFakeLight(true, SolidMeshMaterial.Get());

	for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
	{
		if (VisibilityMap & (1 << ViewIndex))
		{
			const FSceneView* View = Views[ViewIndex];
			FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex);

			// Draw Lines
			const int32 LinesNum = Lines.Num();
			PDI->AddReserveLines(SDPG_World, LinesNum, false, false);
			for (const auto& CurrentLine : Lines)
			{
				PDI->DrawLine(CurrentLine.Start, CurrentLine.End, CurrentLine.Color, SDPG_World, CurrentLine.Thickness, 0, CurrentLine.Thickness > 0);
			}

			// Draw Dashed Lines
			for(int32 DashIdx=0; DashIdx<DashedLines.Num(); DashIdx++)
			{
				const FDashedLine& Dash = DashedLines[DashIdx];

				DrawDashedLine(PDI, Dash.Start, Dash.End, Dash.Color, Dash.DashSize, SDPG_World);
			}

			// Draw Arrows
			const uint32 ArrowsNum = ArrowLines.Num();
			PDI->AddReserveLines(SDPG_World, 5 * ArrowsNum, false, false);
			for (const auto& CurrentArrow : ArrowLines)
			{
				DrawLineArrow(PDI, CurrentArrow.Start, CurrentArrow.End, CurrentArrow.Color, 8.0f);
			}

			// Draw Stars
			for(int32 StarIdx=0; StarIdx<Stars.Num(); StarIdx++)
			{
				const FWireStar& Star = Stars[StarIdx];

				DrawWireStar(PDI, Star.Position, Star.Size, Star.Color, SDPG_World);
			}

			// Draw Cylinders
			for(const auto& Cylinder : Cylinders)
			{
				if (DrawType == SolidAndWireMeshes || DrawType == WireMesh)
				{
					DrawWireCylinder(PDI, Cylinder.Base, FVector(1, 0, 0), FVector(0, 1, 0), FVector(0, 0, 1), Cylinder.Color, Cylinder.Radius, Cylinder.HalfHeight, (DrawType == SolidAndWireMeshes) ? 9 : 16, SDPG_World, DrawType == SolidAndWireMeshes ? 2 : 0, 0, true);
				}

				if (DrawType == SolidAndWireMeshes || DrawType == SolidMesh)
				{
					GetCylinderMesh(Cylinder.Base, FVector(1, 0, 0), FVector(0, 1, 0), FVector(0, 0, 1), Cylinder.Radius, Cylinder.HalfHeight, 16, MaterialCache[0][Cylinder.Color.WithAlpha(DrawAlpha)], SDPG_World, ViewIndex, Collector);
				}
			}

			// Draw Boxes
			for(const auto& Box :  Boxes)
			{
				if (DrawType == SolidAndWireMeshes || DrawType == WireMesh)
				{
					DrawWireBox(PDI, Box.Transform.ToMatrixWithScale(), Box.Box, Box.Color, SDPG_World, DrawType == SolidAndWireMeshes ? 2 : 0, 0, true);
				}
				if (DrawType == SolidAndWireMeshes || DrawType == SolidMesh)
				{
					GetBoxMesh(FTransform(Box.Box.GetCenter()).ToMatrixNoScale() * Box.Transform.ToMatrixWithScale(), Box.Box.GetExtent(), MaterialCache[0][Box.Color.WithAlpha(DrawAlpha)], SDPG_World, ViewIndex, Collector);
				}
			}

			// Draw Boxes
			TArray<FVector> Verts;
			for (auto& CurrentCone : Cones)
			{
				if (DrawType == SolidAndWireMeshes || DrawType == WireMesh)
				{
					DrawWireCone(PDI, Verts, CurrentCone.ConeToWorld, 1, CurrentCone.Angle2, (DrawType == SolidAndWireMeshes) ? 9 : 16, CurrentCone.Color, SDPG_World, DrawType == SolidAndWireMeshes ? 2 : 0, 0, true);
				}
				if (DrawType == SolidAndWireMeshes || DrawType == SolidMesh)
				{
					GetConeMesh(CurrentCone.ConeToWorld, CurrentCone.Angle1, CurrentCone.Angle2, 16, MaterialCache[0][CurrentCone.Color.WithAlpha(DrawAlpha)], SDPG_World, ViewIndex, Collector);
				}
			}

			for (auto It = Spheres.CreateConstIterator(); It; ++It)
			{
				if (PointInView(It->Location, View))
				{
					if (DrawType == SolidAndWireMeshes || DrawType == WireMesh)
					{
						DrawWireSphere(PDI, It->Location, It->Color.WithAlpha(255), It->Radius, 20, SDPG_World, DrawType == SolidAndWireMeshes ? 2 : 0, 0, true);
					}
					if (DrawType == SolidAndWireMeshes || DrawType == SolidMesh)
					{
						GetSphereMesh(It->Location, FVector(It->Radius), 20, 7, MaterialCache[0][It->Color.WithAlpha(DrawAlpha)], SDPG_World, false, ViewIndex, Collector);
					}
				}
			}

			for (auto It = Capsles.CreateConstIterator(); It; ++It)
			{
				if (PointInView(It->Location, View))
				{
					if (DrawType == SolidAndWireMeshes || DrawType == WireMesh)
					{
						const float HalfAxis = FMath::Max<float>(It->HalfHeight - It->Radius, 1.f);
						const FVector BottomEnd = It->Location + It->Radius * It->Z;
						const FVector TopEnd = BottomEnd + (2 * HalfAxis) * It->Z;
						const float CylinderHalfHeight = (TopEnd - BottomEnd).Size() * 0.5;
						const FVector CylinderLocation = BottomEnd + CylinderHalfHeight * It->Z;
						DrawWireCapsule(PDI, CylinderLocation, It->X, It->Y, It->Z, It->Color, It->Radius, It->HalfHeight, (DrawType == SolidAndWireMeshes) ? 9 : 16, SDPG_World, DrawType == SolidAndWireMeshes ? 2 : 0, 0, true);
					}
					if (DrawType == SolidAndWireMeshes || DrawType == SolidMesh)
					{
						GetCapsuleMesh(It->Location, It->X, It->Y, It->Z, It->Color, It->Radius, It->HalfHeight, 16, MaterialCache[0][It->Color.WithAlpha(DrawAlpha)], SDPG_World, false, ViewIndex, Collector);
					}
				}
			}

			for (const auto& Mesh : Meshes)
			{
				FDynamicMeshBuilder MeshBuilder;
				MeshBuilder.AddVertices(Mesh.Vertices);
				MeshBuilder.AddTriangles(Mesh.Indices);

				MeshBuilder.GetMesh(FMatrix::Identity, MaterialCache[Mesh.Color.A == 255 ? 1 : 0][Mesh.Color.WithAlpha(DrawAlpha)], SDPG_World, false, false, ViewIndex, Collector);
			}

		}
	}
}
void FAudioComponentVisualizer::DrawVisualization( const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI )
{
	if(View->Family->EngineShowFlags.AudioRadius)
	{
		const UAudioComponent* AudioComp = Cast<const UAudioComponent>(Component);
		if(AudioComp != NULL)
		{
			const FTransform& Transform = AudioComp->ComponentToWorld;

			TMultiMap<EAttenuationShape::Type, FAttenuationSettings::AttenuationShapeDetails> ShapeDetailsMap;
			AudioComp->CollectAttenuationShapesForVisualization(ShapeDetailsMap);

			FVector Translation = Transform.GetTranslation();
			FVector UnitXAxis   = Transform.GetUnitAxis( EAxis::X );
			FVector UnitYAxis   = Transform.GetUnitAxis( EAxis::Y );
			FVector UnitZAxis   = Transform.GetUnitAxis( EAxis::Z );

			for ( auto It = ShapeDetailsMap.CreateConstIterator(); It; ++It )
			{
				FColor AudioOuterRadiusColor(255, 153, 0);
				FColor AudioInnerRadiusColor(216, 130, 0);

				const FAttenuationSettings::AttenuationShapeDetails& ShapeDetails = It.Value();
				switch(It.Key())
				{
				case EAttenuationShape::Box:

					if (ShapeDetails.Falloff > 0.f)
					{
						DrawOrientedWireBox( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, ShapeDetails.Extents + FVector(ShapeDetails.Falloff), AudioOuterRadiusColor, SDPG_World);
						DrawOrientedWireBox( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, ShapeDetails.Extents, AudioInnerRadiusColor, SDPG_World);
					}
					else
					{
						DrawOrientedWireBox( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, ShapeDetails.Extents, AudioOuterRadiusColor, SDPG_World);
					}
					break;

				case EAttenuationShape::Capsule:

					if (ShapeDetails.Falloff > 0.f)
					{
						DrawWireCapsule( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, AudioOuterRadiusColor, ShapeDetails.Extents.Y + ShapeDetails.Falloff, ShapeDetails.Extents.X + ShapeDetails.Falloff, 25, SDPG_World);
						DrawWireCapsule( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, AudioInnerRadiusColor, ShapeDetails.Extents.Y, ShapeDetails.Extents.X, 25, SDPG_World);
					}
					else
					{
						DrawWireCapsule( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, AudioOuterRadiusColor, ShapeDetails.Extents.Y, ShapeDetails.Extents.X, 25, SDPG_World);
					}
					break;

				case EAttenuationShape::Cone:
					{
						FTransform Origin = Transform;
						Origin.SetScale3D(FVector(1.f));
						Origin.SetTranslation(Translation - (UnitXAxis * ShapeDetails.ConeOffset));

						if (ShapeDetails.Falloff > 0.f || ShapeDetails.Extents.Z > 0.f)
						{
							float ConeRadius = ShapeDetails.Extents.X + ShapeDetails.Falloff + ShapeDetails.ConeOffset;
							float ConeAngle = ShapeDetails.Extents.Y + ShapeDetails.Extents.Z;
							DrawWireSphereCappedCone(PDI, Origin, ConeRadius, ConeAngle, 16, 4, 10, AudioOuterRadiusColor, SDPG_World);

							ConeRadius = ShapeDetails.Extents.X + ShapeDetails.ConeOffset;
							ConeAngle = ShapeDetails.Extents.Y;
							DrawWireSphereCappedCone(PDI, Origin, ConeRadius, ConeAngle, 16, 4, 10, AudioInnerRadiusColor, SDPG_World );
						}
						else
						{
							const float ConeRadius = ShapeDetails.Extents.X + ShapeDetails.ConeOffset;
							const float ConeAngle = ShapeDetails.Extents.Y;
							DrawWireSphereCappedCone(PDI, Origin, ConeRadius, ConeAngle, 16, 4, 10, AudioOuterRadiusColor, SDPG_World );
						}
					}
					break;

				case EAttenuationShape::Sphere:

					if (ShapeDetails.Falloff > 0.f)
					{
						DrawWireSphereAutoSides(PDI, Translation, AudioOuterRadiusColor, ShapeDetails.Extents.X + ShapeDetails.Falloff, SDPG_World);
						DrawWireSphereAutoSides(PDI, Translation, AudioInnerRadiusColor, ShapeDetails.Extents.X, SDPG_World);
					}
					else
					{
						DrawWireSphereAutoSides(PDI, Translation, AudioOuterRadiusColor, ShapeDetails.Extents.X, SDPG_World);
					}
					break;

				default:
					check(false);
				}
			}
		}
	}
}