void FPaperSpriteSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { if (BodySetup != nullptr) { // Show 3D physics if ((ViewFamily.EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = ViewFamily.EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); Collector.RegisterOneFrameMaterialProxy(CollisionMaterialInstance); // Draw the sprite body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (ViewFamily.EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. const FColor CollisionColor = FColor(220,149,223,255); const bool bUseSeparateColorPerHull = (Owner == nullptr); const bool bDrawSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()).ToFColor(true), CollisionMaterialInstance, bUseSeparateColorPerHull, bDrawSolid, false, ViewIndex, Collector); } } } } } FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }
void FPaperTileMapRenderSceneProxy::DrawNormalGridLines(FPrimitiveDrawInterface* PDI, const FLinearColor& Color, int32 LayerIndex) const { const FMatrix& LocalToWorldMat = GetLocalToWorld(); const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw horizontal lines on the selection for (int32 Y = 0; Y <= TileMap->MapHeight; ++Y) { int32 X = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, LayerIndex)); X = TileMap->MapWidth; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, LayerIndex)); PDI->DrawLine(LocalToWorldMat.TransformPosition(Start), LocalToWorldMat.TransformPosition(End), Color, DPG, 0.0f, WireDepthBias); } // Draw vertical lines for (int32 X = 0; X <= TileMap->MapWidth; ++X) { int32 Y = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, LayerIndex)); Y = TileMap->MapHeight; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, LayerIndex)); PDI->DrawLine(LocalToWorldMat.TransformPosition(Start), LocalToWorldMat.TransformPosition(End), Color, DPG, 0.0f, WireDepthBias); } }
void FPaperTileMapRenderSceneProxy::DrawHexagonalGridLines(FPrimitiveDrawInterface* PDI, const FLinearColor& Color, int32 LayerIndex) const { //@TODO: This isn't very efficient const FMatrix& LocalToWorldMat = GetLocalToWorld(); const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); TArray<FVector> Poly; Poly.Empty(6); for (int32 Y = 0; Y < TileMap->MapHeight; ++Y) { for (int32 X = 0; X < TileMap->MapWidth; ++X) { Poly.Reset(); TileMap->GetTilePolygon(X, Y, LayerIndex, Poly); FVector LastVertexWS = LocalToWorldMat.TransformPosition(Poly[5]); for (int32 VI = 0; VI < Poly.Num(); ++VI) { FVector ThisVertexWS = LocalToWorldMat.TransformPosition(Poly[VI]); PDI->DrawLine(LastVertexWS, ThisVertexWS, Color, DPG, 0.0f, WireDepthBias); LastVertexWS = ThisVertexWS; } } } }
/** * Draw the scene proxy as a dynamic element * * @param PDI - draw interface to render to * @param View - current view */ virtual void DrawDynamicElements(FPrimitiveDrawInterface* PDI,const FSceneView* View) { QUICK_SCOPE_CYCLE_COUNTER( STAT_ArrowSceneProxy_DrawDynamicElements ); FMatrix EffectiveLocalToWorld; #if WITH_EDITOR if (bLightAttachment) { EffectiveLocalToWorld = GetLocalToWorld().GetMatrixWithoutScale(); } else #endif //WITH_EDITOR { EffectiveLocalToWorld = GetLocalToWorld(); } DrawDirectionalArrow(PDI,EffectiveLocalToWorld,ArrowColor,ArrowSize * 3.0f * ARROW_SCALE,ARROW_SCALE,GetDepthPriorityGroup(View)); }
//!< FPrimitiveSceneProxy virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, class FMeshElementCollector& Collector) const override { FDynamicMeshBuilder MeshBuilder; const auto Num = 20; const auto DeltaUV = 1.0f / (Num - 1); TArray<FDynamicMeshVertex> Vertices; Vertices.Reserve(Num * Num); for (auto i = 0; i < Num; ++i) { for (auto j = 0; j < Num; ++j) { const auto UV = FVector2D(DeltaUV * j, DeltaUV * i); FDynamicMeshVertex Vertex; Vertex.Position = GetPosition(UV); Vertex.TextureCoordinate = GetUV(UV); const auto Edge01 = GetPosition(UV + FVector2D(0.01f, 0.0f)) - Vertex.Position; const auto Edge02 = GetPosition(UV - FVector2D(0.0f, 0.01f)) - Vertex.Position; Vertex.TangentX = Edge01.GetSafeNormal(); Vertex.TangentZ = (Edge02 ^ Edge01).GetSafeNormal(); Vertex.Color = FColor::Green; Vertices.Add(Vertex); } } MeshBuilder.AddVertices(Vertices); TArray<int32> Indices; Indices.Reserve((Num - 1) * (Num - 1) * 6); for (auto i = 0; i < Num - 1; ++i) { for (auto j = 0; j < Num - 1; ++j) { const auto Index = j + i * Num; Indices.Add(Index); Indices.Add(Index + Num); Indices.Add(Index + 1); Indices.Add(Index + 1); Indices.Add(Index + Num); Indices.Add(Index + Num + 1); } } MeshBuilder.AddTriangles(Indices); auto MaterialRenderProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(IsSelected()); if (nullptr != MaterialInterface) { MaterialRenderProxy = MaterialInterface->GetRenderProxy(false); } if (Views[0]->Family->EngineShowFlags.Wireframe) { MaterialRenderProxy = GEngine->WireframeMaterial->GetRenderProxy(IsSelected()); } MeshBuilder.GetMesh(GetLocalToWorld(), MaterialRenderProxy, 0, false, false, 0, Collector); }
Matrix3 plMaxNodeBase::GetLocalToParent(TimeValue t) { // l2w = l2p * parentL2W // l2w * Inverse(parentL2W) = l2p // l2w * parentW2L = l2p Matrix3 l2w = GetLocalToWorld(t); Matrix3 w2p(true); if( !GetParentNode()->IsRootNode() ) w2p = GetWorldToParent(t); Matrix3 l2p = l2w * w2p; return l2p; }
void FPaperTileMapRenderSceneProxy::DrawBoundsForLayer(FPrimitiveDrawInterface* PDI, const FLinearColor& Color, int32 LayerIndex) const { const FMatrix& LocalToWorldMat = GetLocalToWorld(); const FVector TL(LocalToWorldMat.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, 0, LayerIndex))); const FVector TR(LocalToWorldMat.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, 0, LayerIndex))); const FVector BL(LocalToWorldMat.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, TileMap->MapHeight, LayerIndex))); const FVector BR(LocalToWorldMat.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, TileMap->MapHeight, LayerIndex))); PDI->DrawLine(TL, TR, Color, SDPG_Foreground, 0.0f, WireDepthBias); PDI->DrawLine(TR, BR, Color, SDPG_Foreground, 0.0f, WireDepthBias); PDI->DrawLine(BR, BL, Color, SDPG_Foreground, 0.0f, WireDepthBias); PDI->DrawLine(BL, TL, Color, SDPG_Foreground, 0.0f, WireDepthBias); }
virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override { QUICK_SCOPE_CYCLE_COUNTER( STAT_BoxSceneProxy_GetDynamicMeshElements ); const FMatrix& LocalToWorld = GetLocalToWorld(); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; const FLinearColor DrawColor = GetViewSelectionColor(BoxColor, *View, IsSelected(), IsHovered(), false, IsIndividuallySelected() ); FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); DrawOrientedWireBox(PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetScaledAxis( EAxis::X ), LocalToWorld.GetScaledAxis( EAxis::Y ), LocalToWorld.GetScaledAxis( EAxis::Z ), BoxExtents, DrawColor, SDPG_World); } } }
void plAnimPath::MakeDrawList(hsTArray<uint16_t>& idx, hsTArray<hsPoint3>& pos) { hsMatrix44 resetL2W = GetLocalToWorld(); hsMatrix44 resetW2L = GetWorldToLocal(); hsMatrix44 ident; ident.Reset(); SetTransform(ident, ident); float numSegs = fRadius; // crude estimate of arclength if (numSegs>100) numSegs=100; float animLen = GetLength(); float timeInc = animLen/numSegs; float time=0; hsPoint3 p1, p2; SetCurTime(0, kCalcPosOnly); GetPosition(&p1); time += timeInc; bool quit=false; while(! quit && time < animLen+timeInc) { if (time > animLen) { time = animLen; quit=true; } SetCurTime(time, kCalcPosOnly); GetPosition(&p2); IMakeSegment(idx, pos, p1, p2); time += timeInc; p1 = p2; } SetTransform(resetL2W, resetW2L); }
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 ); } } }
void FTangoPointCloudSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily & ViewFamily, uint32 VisibilityMap, FMeshElementCollector & Collector) const { for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { //Essentially, which camera we are using const FSceneView* View = Views[ViewIndex]; //Ask for a new render batch and link it to our data FMeshBatch& Mesh = Collector.AllocateMesh(); Mesh.VertexFactory = &VertexFactory; Mesh.MaterialRenderProxy = Material->GetRenderProxy(IsSelected()); Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.DepthPriorityGroup = SDPG_World; Mesh.bCanApplyViewModeOverrides = false; //GL_Points render, still need to work out how to set GL_PointSize Mesh.Type = PT_PointList; //Tell the render object how to index our data. FMeshBatchElement& BatchElement = Mesh.Elements[0]; BatchElement.IndexBuffer = &IndexBuffer; //Give all the "default" uniforms to help render. (Transform etc.) BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); BatchElement.FirstIndex = 0; BatchElement.NumPrimitives = IndexBuffer.Indices.Num() / 3; BatchElement.MinVertexIndex = 0; BatchElement.MaxVertexIndex = VertexBuffer.Vertices.Num() - 1; //All done! Collector.AddMesh(ViewIndex, Mesh); } } }
void FGeometryCacheSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { SCOPE_CYCLE_COUNTER(STAT_GeometryCacheSceneProxy_GetMeshElements); // Set up wireframe material (if needed) const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe; FColoredMaterialRenderProxy* WireframeMaterialInstance = NULL; if (bWireframe) { WireframeMaterialInstance = new FColoredMaterialRenderProxy( GEngine->WireframeMaterial ? GEngine->WireframeMaterial->GetRenderProxy(IsSelected()) : NULL, FLinearColor(0, 0.5f, 1.f) ); Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance); } // Iterate over sections for (const FGeomCacheTrackProxy* TrackProxy : Sections ) { // QQQ if (TrackProxy != nullptr) { INC_DWORD_STAT_BY(STAT_GeometryCacheSceneProxy_MeshBatchCount, TrackProxy->MeshData->BatchesInfo.Num()); int32 BatchIndex = 0; for (FGeometryCacheMeshBatchInfo& BatchInfo : TrackProxy->MeshData->BatchesInfo) { FMaterialRenderProxy* MaterialProxy = bWireframe ? WireframeMaterialInstance : TrackProxy->Materials[BatchIndex]->GetRenderProxy(IsSelected()); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; // Draw the mesh. FMeshBatch& Mesh = Collector.AllocateMesh(); FMeshBatchElement& BatchElement = Mesh.Elements[0]; BatchElement.IndexBuffer = &TrackProxy->IndexBuffer; Mesh.bWireframe = bWireframe; Mesh.VertexFactory = &TrackProxy->VertexFactory; Mesh.MaterialRenderProxy = MaterialProxy; BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(TrackProxy->WorldMatrix * GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); BatchElement.FirstIndex = BatchInfo.StartIndex; BatchElement.NumPrimitives = BatchInfo.NumTriangles; BatchElement.MinVertexIndex = 0; BatchElement.MaxVertexIndex = TrackProxy->VertexBuffer.Vertices.Num() - 1; Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.Type = PT_TriangleList; Mesh.DepthPriorityGroup = SDPG_World; Mesh.bCanApplyViewModeOverrides = false; Collector.AddMesh(ViewIndex, Mesh); INC_DWORD_STAT_BY(STAT_GeometryCacheSceneProxy_TriangleCount, BatchElement.NumPrimitives); } } ++BatchIndex; } } } // Draw bounds #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { // Render bounds RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); } } #endif }
void FPaperTileMapRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { SCOPE_CYCLE_COUNTER(STAT_TileMap_GetDynamicMeshElements); checkSlow(IsInRenderingThread()); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { SCOPE_CYCLE_COUNTER(STAT_TileMap_EditorWireDrawing); if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); // Draw the tile maps //@TODO: RenderThread race condition if (TileMap != nullptr) { if ((View->Family->EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (UBodySetup2D* BodySetup2D = Cast<UBodySetup2D>(TileMap->BodySetup)) { //@TODO: Draw 2D debugging geometry } else if (UBodySetup* BodySetup = TileMap->BodySetup) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = View->Family->EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); // Draw the static mesh's body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (View->Family->EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. FColor CollisionColor = FColor(157, 149, 223, 255); const bool bPerHullColor = false; const bool bDrawSimpleSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()).ToFColor(true), CollisionMaterialInstance, bPerHullColor, bDrawSimpleSolid, UseEditorDepthTest(), ViewIndex, Collector); } } } // Draw the bounds RenderBounds(PDI, View->Family->EngineShowFlags, GetBounds(), IsSelected()); #if WITH_EDITOR const bool bShowAsSelected = IsSelected(); const bool bEffectivelySelected = bShowAsSelected || IsHovered(); const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw separation wires if selected const FLinearColor OverrideColor = GetSelectionColor(FLinearColor::White, bShowAsSelected, IsHovered(), /*bUseOverlayIntensity=*/ false); // Draw the debug outline if (bEffectivelySelected) { const int32 SelectedLayerIndex = (OnlyLayerIndex != INDEX_NONE) ? OnlyLayerIndex : TileMap->SelectedLayerIndex; if (bShowPerLayerGrid) { if (OnlyLayerIndex == INDEX_NONE) { // Draw a bound for every layer but the selected one (and even that one if the per-tile grid is off) for (int32 LayerIndex = 0; LayerIndex < TileMap->TileLayers.Num(); ++LayerIndex) { if ((LayerIndex != SelectedLayerIndex) || !bShowPerTileGrid) { DrawBoundsForLayer(PDI, OverrideColor, LayerIndex); } } } else if (!bShowPerTileGrid) { DrawBoundsForLayer(PDI, OverrideColor, OnlyLayerIndex); } } if (bShowPerTileGrid && (SelectedLayerIndex != INDEX_NONE)) { switch (TileMap->ProjectionMode) { default: case ETileMapProjectionMode::Orthogonal: case ETileMapProjectionMode::IsometricDiamond: DrawNormalGridLines(PDI, OverrideColor, SelectedLayerIndex); break; case ETileMapProjectionMode::IsometricStaggered: DrawStaggeredGridLines(PDI, OverrideColor, SelectedLayerIndex); break; case ETileMapProjectionMode::HexagonalStaggered: DrawHexagonalGridLines(PDI, OverrideColor, SelectedLayerIndex); break; } } } else if (View->Family->EngineShowFlags.Grid && bShowOutlineWhenUnselected) { // Draw a layer rectangle even when not selected, so you can see where the tile map is in the editor DrawBoundsForLayer(PDI, WireframeColor, /*LayerIndex=*/ (OnlyLayerIndex != INDEX_NONE) ? OnlyLayerIndex : 0); } #endif } } } // Draw all of the queued up sprites FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }
virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override { QUICK_SCOPE_CYCLE_COUNTER( STAT_DrawFrustumSceneProxy_DrawDynamicElements ); FVector Direction(1,0,0); FVector LeftVector(0,1,0); FVector UpVector(0,0,1); FVector Verts[8]; // FOVAngle controls the horizontal angle. const float HozHalfAngleInRadians = FMath::DegreesToRadians(FrustumAngle * 0.5f); float HozLength = 0.0f; float VertLength = 0.0f; if (FrustumAngle > 0.0f) { HozLength = FrustumStartDist * FMath::Tan(HozHalfAngleInRadians); VertLength = HozLength / FrustumAspectRatio; } else { const float OrthoWidth = (FrustumAngle == 0.0f) ? 1000.0f : -FrustumAngle; HozLength = OrthoWidth * 0.5f; VertLength = HozLength / FrustumAspectRatio; } // near plane verts Verts[0] = (Direction * FrustumStartDist) + (UpVector * VertLength) + (LeftVector * HozLength); Verts[1] = (Direction * FrustumStartDist) + (UpVector * VertLength) - (LeftVector * HozLength); Verts[2] = (Direction * FrustumStartDist) - (UpVector * VertLength) - (LeftVector * HozLength); Verts[3] = (Direction * FrustumStartDist) - (UpVector * VertLength) + (LeftVector * HozLength); if (FrustumAngle > 0.0f) { HozLength = FrustumEndDist * FMath::Tan(HozHalfAngleInRadians); VertLength = HozLength / FrustumAspectRatio; } // far plane verts Verts[4] = (Direction * FrustumEndDist) + (UpVector * VertLength) + (LeftVector * HozLength); Verts[5] = (Direction * FrustumEndDist) + (UpVector * VertLength) - (LeftVector * HozLength); Verts[6] = (Direction * FrustumEndDist) - (UpVector * VertLength) - (LeftVector * HozLength); Verts[7] = (Direction * FrustumEndDist) - (UpVector * VertLength) + (LeftVector * HozLength); for (int32 X = 0; X < 8; ++X) { Verts[X] = GetLocalToWorld().TransformPosition(Verts[X]); } for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); const FSceneView* View = Views[ViewIndex]; const uint8 DepthPriorityGroup = GetDepthPriorityGroup(View); PDI->DrawLine( Verts[0], Verts[1], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[1], Verts[2], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[2], Verts[3], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[3], Verts[0], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[4], Verts[5], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[5], Verts[6], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[6], Verts[7], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[7], Verts[4], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[0], Verts[4], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[1], Verts[5], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[2], Verts[6], FrustumColor, DepthPriorityGroup ); PDI->DrawLine( Verts[3], Verts[7], FrustumColor, DepthPriorityGroup ); } } }
virtual void OnTransformChanged() override { Origin = GetLocalToWorld().GetOrigin(); }
Matrix3 plMaxNodeBase::GetWorldToLocal(TimeValue t) { Matrix3 l2w = GetLocalToWorld(t); Matrix3 w2l = Inverse(l2w); return w2l; }
hsMatrix44 plMaxNodeBase::GetLocalToWorld44(TimeValue t) { Matrix3 m3 = GetLocalToWorld(t); hsMatrix44 m44 = Matrix3ToMatrix44(m3); return m44; }
void FPaperTileMapRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { QUICK_SCOPE_CYCLE_COUNTER(STAT_FPaperTileMapRenderSceneProxy_GetDynamicMeshElements); checkSlow(IsInRenderingThread()); // Slight depth bias so that the wireframe grid overlay doesn't z-fight with the tiles themselves const float DepthBias = 0.0001f; for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); // Draw the tile maps //@TODO: RenderThread race condition if (TileMap != nullptr) { FColor WireframeColor = FColor(0, 255, 255, 255); if ((View->Family->EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (UBodySetup2D* BodySetup2D = Cast<UBodySetup2D>(TileMap->BodySetup)) { //@TODO: Draw 2D debugging geometry } else if (UBodySetup* BodySetup = TileMap->BodySetup) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = View->Family->EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); // Draw the static mesh's body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (View->Family->EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. FColor CollisionColor = FColor(157, 149, 223, 255); const bool bPerHullColor = false; const bool bDrawSimpleSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()), CollisionMaterialInstance, bPerHullColor, bDrawSimpleSolid, UseEditorDepthTest(), ViewIndex, Collector); } } } // Draw the bounds RenderBounds(PDI, View->Family->EngineShowFlags, GetBounds(), IsSelected()); #if WITH_EDITOR // Draw the debug outline if (View->Family->EngineShowFlags.Grid) { const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw separation wires if selected FLinearColor OverrideColor; bool bUseOverrideColor = false; const bool bShowAsSelected = !(GIsEditor && View->Family->EngineShowFlags.Selection) || IsSelected(); if (bShowAsSelected || IsHovered()) { bUseOverrideColor = true; OverrideColor = GetSelectionColor(FLinearColor::White, bShowAsSelected, IsHovered()); } FTransform LocalToWorld(GetLocalToWorld()); if (bUseOverrideColor) { const int32 SelectedLayerIndex = TileMap->SelectedLayerIndex; // Draw a bound for any invisible layers for (int32 LayerIndex = 0; LayerIndex < TileMap->TileLayers.Num(); ++LayerIndex) { if (LayerIndex != SelectedLayerIndex) { const FVector TL(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, 0, LayerIndex))); const FVector TR(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, 0, LayerIndex))); const FVector BL(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, TileMap->MapHeight, LayerIndex))); const FVector BR(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, TileMap->MapHeight, LayerIndex))); PDI->DrawLine(TL, TR, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(TR, BR, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(BR, BL, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(BL, TL, OverrideColor, DPG, 0.0f, DepthBias); } } if (SelectedLayerIndex != INDEX_NONE) { // Draw horizontal lines on the selection for (int32 Y = 0; Y <= TileMap->MapHeight; ++Y) { int32 X = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); X = TileMap->MapWidth; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); PDI->DrawLine(LocalToWorld.TransformPosition(Start), LocalToWorld.TransformPosition(End), OverrideColor, DPG, 0.0f, DepthBias); } // Draw vertical lines for (int32 X = 0; X <= TileMap->MapWidth; ++X) { int32 Y = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); Y = TileMap->MapHeight; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); PDI->DrawLine(LocalToWorld.TransformPosition(Start), LocalToWorld.TransformPosition(End), OverrideColor, DPG, 0.0f, DepthBias); } } } } #endif } } } // Draw all of the queued up sprites FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }
void FPaperTileMapRenderSceneProxy::DrawStaggeredGridLines(FPrimitiveDrawInterface* PDI, const FLinearColor& Color, int32 LayerIndex) const { TArray<FVector> Poly; Poly.Empty(4); const FMatrix& LocalToWorldMat = GetLocalToWorld(); const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); FVector CornerPosition; FVector OffsetYFactor; FVector StepX; FVector StepY; TileMap->GetTileToLocalParameters(/*out*/ CornerPosition, /*out*/ StepX, /*out*/ StepY, /*out*/ OffsetYFactor); const FVector PartialZ = (TileMap->SeparationPerLayer * LayerIndex) * PaperAxisZ; const FVector TotalOffset = CornerPosition + PartialZ; const bool bStaggerEven = false; const FVector TopCenterStart = TotalOffset + StepX * 0.5f + (StepX * -0.5f) + StepY; for (int32 X = 0-((TileMap->MapHeight+1)/2); X < TileMap->MapWidth; ++X) { int32 XTop = FMath::Max(X, 0); int32 YTop = FMath::Max(-2 * X, 0); if (X < 0) { XTop--; YTop--; } // A is top of center top row cell Poly.Reset(); TileMap->GetTilePolygon(XTop, YTop, LayerIndex, Poly); const FVector LSA = Poly[0]; // Determine the bottom row cell int32 YBottom = TileMap->MapHeight - 1; int32 XBottom = X + (TileMap->MapHeight + 1) / 2; const int32 XExcess = FMath::Max(XBottom - TileMap->MapWidth, 0); XBottom -= XExcess; YBottom -= XExcess * 2; if (XBottom == TileMap->MapWidth) { YBottom -= ((TileMap->MapHeight & 1) != 0) ? 0 : 1; } // Bottom center Poly.Reset(); TileMap->GetTilePolygon(XBottom, YBottom, LayerIndex, Poly); const FVector LSB = Poly[2]; PDI->DrawLine(LocalToWorldMat.TransformPosition(LSA), LocalToWorldMat.TransformPosition(LSB), Color, DPG, 0.0f, WireDepthBias); } for (int32 X = 0; X < TileMap->MapWidth + ((TileMap->MapHeight + 1) / 2) + 1; ++X) { const int32 XTop = FMath::Min(X, TileMap->MapWidth); const int32 YTop = FMath::Max(2 * (X - TileMap->MapWidth), 0); // A is top center of top row cell Poly.Reset(); TileMap->GetTilePolygon(XTop, YTop, LayerIndex, Poly); const FVector LSA = Poly[0]; // Determine the bottom row cell int32 YBottom = TileMap->MapHeight; int32 XBottom = X - ((TileMap->MapHeight+1) / 2); const int32 XExcess = FMath::Max(-XBottom, 0); XBottom += XExcess; YBottom -= XExcess * 2; if (XExcess > 0) { YBottom += (TileMap->MapHeight & 1); } // Bottom left Poly.Reset(); TileMap->GetTilePolygon(XBottom, YBottom, LayerIndex, Poly); const FVector LSB = Poly[3]; PDI->DrawLine(LocalToWorldMat.TransformPosition(LSA), LocalToWorldMat.TransformPosition(LSB), Color, DPG, 0.0f, WireDepthBias); } }