コード例 #1
0
void FStaticMeshEditorViewportClient::Draw(const FSceneView* View,FPrimitiveDrawInterface* PDI)
{
	FEditorViewportClient::Draw(View, PDI);

	if (bShowCollision && StaticMesh->BodySetup)
	{
		const FColor SelectedColor(149, 223, 157);
		const FColor UnselectedColor(157, 149, 223);

		// Draw bodies
		FKAggregateGeom* AggGeom = &StaticMesh->BodySetup->AggGeom;

		for (int32 i = 0; i < AggGeom->SphereElems.Num(); ++i)
		{
			HSMECollisionProxy* HitProxy = new HSMECollisionProxy(KPT_Sphere, i);
			PDI->SetHitProxy(HitProxy);

			const FColor CollisionColor = StaticMeshEditorPtr.Pin()->IsSelectedPrim(HitProxy->PrimData) ? SelectedColor : UnselectedColor;
			const FKSphereElem& SphereElem = AggGeom->SphereElems[i];
			const FTransform ElemTM = SphereElem.GetTransform();
			SphereElem.DrawElemWire(PDI, ElemTM, 1.f, CollisionColor);

			PDI->SetHitProxy(NULL);
		}

		for (int32 i = 0; i < AggGeom->BoxElems.Num(); ++i)
		{
			HSMECollisionProxy* HitProxy = new HSMECollisionProxy(KPT_Box, i);
			PDI->SetHitProxy(HitProxy);

			const FColor CollisionColor = StaticMeshEditorPtr.Pin()->IsSelectedPrim(HitProxy->PrimData) ? SelectedColor : UnselectedColor;
			const FKBoxElem& BoxElem = AggGeom->BoxElems[i];
			const FTransform ElemTM = BoxElem.GetTransform();
			BoxElem.DrawElemWire(PDI, ElemTM, 1.f, CollisionColor);

			PDI->SetHitProxy(NULL);
		}

		for (int32 i = 0; i < AggGeom->SphylElems.Num(); ++i)
		{
			HSMECollisionProxy* HitProxy = new HSMECollisionProxy(KPT_Sphyl, i);
			PDI->SetHitProxy(HitProxy);

			const FColor CollisionColor = StaticMeshEditorPtr.Pin()->IsSelectedPrim(HitProxy->PrimData) ? SelectedColor : UnselectedColor;
			const FKSphylElem& SphylElem = AggGeom->SphylElems[i];
			const FTransform ElemTM = SphylElem.GetTransform();
			SphylElem.DrawElemWire(PDI, ElemTM, 1.f, CollisionColor);

			PDI->SetHitProxy(NULL);
		}

		for (int32 i = 0; i < AggGeom->ConvexElems.Num(); ++i)
		{
			HSMECollisionProxy* HitProxy = new HSMECollisionProxy(KPT_Convex, i);
			PDI->SetHitProxy(HitProxy);

			const FColor CollisionColor = StaticMeshEditorPtr.Pin()->IsSelectedPrim(HitProxy->PrimData) ? SelectedColor : UnselectedColor;
			const FKConvexElem& ConvexElem = AggGeom->ConvexElems[i];
			const FTransform ElemTM = ConvexElem.GetTransform();
			ConvexElem.DrawElemWire(PDI, ElemTM, CollisionColor);

			PDI->SetHitProxy(NULL);
		}
	}

	if( bShowSockets )
	{
		const FColor SocketColor = FColor(255, 128, 128);

		for(int32 i=0; i < StaticMesh->Sockets.Num(); i++)
		{
			UStaticMeshSocket* Socket = StaticMesh->Sockets[i];
			if(Socket)
			{
				FMatrix SocketTM;
				Socket->GetSocketMatrix(SocketTM, StaticMeshComponent);
				PDI->SetHitProxy( new HSMESocketProxy(i) );
				DrawWireDiamond(PDI, SocketTM, 5.f, SocketColor, SDPG_Foreground);
				PDI->SetHitProxy( NULL );
			}
		}
	}

	// Draw any edges that are currently selected by the user
	if( SelectedEdgeIndices.Num() > 0 )
	{
		for(int32 VertexIndex = 0; VertexIndex < SelectedEdgeVertices.Num(); VertexIndex += 2)
		{
			FVector EdgeVertices[ 2 ];
			EdgeVertices[ 0 ] = SelectedEdgeVertices[VertexIndex];
			EdgeVertices[ 1 ] = SelectedEdgeVertices[VertexIndex + 1];

			PDI->DrawLine(
				StaticMeshComponent->ComponentToWorld.TransformPosition( EdgeVertices[ 0 ] ),
				StaticMeshComponent->ComponentToWorld.TransformPosition( EdgeVertices[ 1 ] ),
				FColor( 255, 255, 0 ),
				SDPG_World );
		}
	}


	if( bDrawNormals || bDrawTangents || bDrawBinormals )
	{
		FStaticMeshLODResources& LODModel = StaticMesh->RenderData->LODResources[StaticMeshEditorPtr.Pin()->GetCurrentLODIndex()];
		FIndexArrayView Indices = LODModel.IndexBuffer.GetArrayView();
		uint32 NumIndices = Indices.Num();

		FMatrix LocalToWorldInverseTranspose = StaticMeshComponent->ComponentToWorld.ToMatrixWithScale().InverseFast().GetTransposed();
		for (uint32 i = 0; i < NumIndices; i++)
		{
			const FVector& VertexPos = LODModel.PositionVertexBuffer.VertexPosition( Indices[i] );

			const FVector WorldPos = StaticMeshComponent->ComponentToWorld.TransformPosition( VertexPos );
			const FVector& Normal = LODModel.VertexBuffer.VertexTangentZ( Indices[i] ); 
			const FVector& Binormal = LODModel.VertexBuffer.VertexTangentY( Indices[i] ); 
			const FVector& Tangent = LODModel.VertexBuffer.VertexTangentX( Indices[i] ); 

			const float Len = 5.0f;

			if( bDrawNormals )
			{
				PDI->DrawLine( WorldPos, WorldPos+LocalToWorldInverseTranspose.TransformVector( Normal ).SafeNormal() * Len, FLinearColor( 0.0f, 1.0f, 0.0f), SDPG_World );
			}

			if( bDrawTangents )
			{
				PDI->DrawLine( WorldPos, WorldPos+LocalToWorldInverseTranspose.TransformVector( Tangent ).SafeNormal() * Len, FLinearColor( 1.0f, 0.0f, 0.0f), SDPG_World );
			}

			if( bDrawBinormals )
			{
				PDI->DrawLine( WorldPos, WorldPos+LocalToWorldInverseTranspose.TransformVector( Binormal ).SafeNormal() * Len, FLinearColor( 0.0f, 0.0f, 1.0f), SDPG_World );
			}
		}	
	}


	if( bShowPivot )
	{
		FUnrealEdUtils::DrawWidget(View, PDI, StaticMeshComponent->ComponentToWorld.ToMatrixWithScale(), 0, 0, EAxisList::All, EWidgetMovementMode::WMM_Translate, false);
	}

	if( bDrawAdditionalData )
	{
		const TArray<UAssetUserData*>* UserDataArray = StaticMesh->GetAssetUserDataArray();
		if (UserDataArray != NULL)
		{
			for (int32 AdditionalDataIndex = 0; AdditionalDataIndex < UserDataArray->Num(); ++AdditionalDataIndex)
			{
				if ((*UserDataArray)[AdditionalDataIndex] != NULL)
				{
					(*UserDataArray)[AdditionalDataIndex]->Draw(PDI, View);
				}
			}
		}
	}
}
コード例 #2
0
bool FStaticMeshEditorViewportClient::InputWidgetDelta( FViewport* Viewport, EAxisList::Type CurrentAxis, FVector& Drag, FRotator& Rot, FVector& Scale )
{
	bool bHandled = false;
	if (bManipulating)
	{
		if (CurrentAxis != EAxisList::None)
		{
			UStaticMeshSocket* SelectedSocket = StaticMeshEditorPtr.Pin()->GetSelectedSocket();
			if(SelectedSocket)
			{
				UProperty* ChangedProperty = NULL;
				const FWidget::EWidgetMode MoveMode = GetWidgetMode();
				if(MoveMode == FWidget::WM_Rotate)
				{
					ChangedProperty = FindField<UProperty>( UStaticMeshSocket::StaticClass(), "RelativeRotation" );
					SelectedSocket->PreEditChange(ChangedProperty);

					FRotator CurrentRot = SelectedSocket->RelativeRotation;
					FRotator SocketWinding, SocketRotRemainder;
					CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder);

					const FQuat ActorQ = SocketRotRemainder.Quaternion();
					const FQuat DeltaQ = Rot.Quaternion();
					const FQuat ResultQ = DeltaQ * ActorQ;
					const FRotator NewSocketRotRem = FRotator( ResultQ );
					FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder;
					DeltaRot.Normalize();

					SelectedSocket->RelativeRotation += DeltaRot;
					SelectedSocket->RelativeRotation = SelectedSocket->RelativeRotation.Clamp();
				}
				else if(MoveMode == FWidget::WM_Translate)
				{
					ChangedProperty = FindField<UProperty>( UStaticMeshSocket::StaticClass(), "RelativeLocation" );
					SelectedSocket->PreEditChange(ChangedProperty);

					//FRotationMatrix SocketRotTM( SelectedSocket->RelativeRotation );
					//FVector SocketMove = SocketRotTM.TransformVector( Drag );

					SelectedSocket->RelativeLocation += Drag;
				}
				if ( ChangedProperty )
				{			
					FPropertyChangedEvent PropertyChangedEvent( ChangedProperty );
					SelectedSocket->PostEditChangeProperty(PropertyChangedEvent);
				}

				StaticMeshEditorPtr.Pin()->GetStaticMesh()->MarkPackageDirty();
			}
			else
			{
				const bool bSelectedPrim = StaticMeshEditorPtr.Pin()->HasSelectedPrims();
				if (bSelectedPrim && CurrentAxis != EAxisList::None)
				{
					const FWidget::EWidgetMode MoveMode = GetWidgetMode();
					if (MoveMode == FWidget::WM_Rotate)
					{
						StaticMeshEditorPtr.Pin()->RotateSelectedPrims(Rot);
					}
					else if (MoveMode == FWidget::WM_Scale)
					{
						StaticMeshEditorPtr.Pin()->ScaleSelectedPrims(Scale);
					}
					else if (MoveMode == FWidget::WM_Translate)
					{
						StaticMeshEditorPtr.Pin()->TranslateSelectedPrims(Drag);
					}

					StaticMeshEditorPtr.Pin()->GetStaticMesh()->MarkPackageDirty();
				}
			}
		}

		Invalidate();		
		bHandled = true;
	}

	return bHandled;
}