You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb stephen.holmes [FYI] zak.middleton #preflight 61f7d18b114ec25fe09648d6 #ROBOMERGE-OWNER: Andrew.Davidson #ROBOMERGE-AUTHOR: andrew.davidson #ROBOMERGE-SOURCE: CL 18788533 in //UE5/Release-5.0/... via CL 18788583 via CL 18788850 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v908-18788545) #ROBOMERGE-CONFLICT from-shelf #preflight 61f7eb7a114ec25fe0990f8c [CL 18789644 by Andrew Davidson in ue5-main branch]
255 lines
8.9 KiB
C++
255 lines
8.9 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "DatasmithSketchUpUtils.h"
|
|
#include "DatasmithSketchUpCommon.h"
|
|
#include "DatasmithSketchUpString.h"
|
|
#include "DatasmithSketchUpSummary.h"
|
|
|
|
#include "IDatasmithSceneElements.h"
|
|
|
|
// SketchUp SDK.
|
|
#include "DatasmithSketchUpSDKBegins.h"
|
|
|
|
#include "SketchUpAPI/model/camera.h"
|
|
#include "SketchUpAPI/model/component_definition.h"
|
|
#include "SketchUpAPI/model/component_instance.h"
|
|
#include "SketchUpAPI/model/drawing_element.h"
|
|
#include "SketchUpAPI/model/edge.h"
|
|
#include "SketchUpAPI/model/entities.h"
|
|
#include "SketchUpAPI/model/entity.h"
|
|
#include "SketchUpAPI/model/face.h"
|
|
#include "SketchUpAPI/model/geometry.h"
|
|
#include "SketchUpAPI/model/group.h"
|
|
#include "SketchUpAPI/model/layer.h"
|
|
#include "SketchUpAPI/model/material.h"
|
|
#include "SketchUpAPI/model/mesh_helper.h"
|
|
#include "SketchUpAPI/model/model.h"
|
|
#include "SketchUpAPI/model/scene.h"
|
|
#include "SketchUpAPI/model/texture.h"
|
|
#include "SketchUpAPI/model/uv_helper.h"
|
|
|
|
#include "DatasmithSketchUpSDKCeases.h"
|
|
|
|
// Imath third party library.
|
|
#include "Imath/ImathMatrixAlgo.h"
|
|
|
|
|
|
|
|
using namespace DatasmithSketchUp;
|
|
|
|
DatasmithSketchUp::FEntityIDType DatasmithSketchUpUtils::GetEntityID(SUEntityRef InEntityRef)
|
|
{
|
|
int32 Id = 0;
|
|
SUEntityGetID(InEntityRef, &Id); // we can ignore the returned SU_RESULT
|
|
return FEntityIDType{ Id };
|
|
}
|
|
|
|
SULayerRef DatasmithSketchUpUtils::GetEffectiveLayer(
|
|
SUComponentInstanceRef InComponentInstanceRef, // valid SketckUp component instance
|
|
SULayerRef InInheritedLayerRef
|
|
)
|
|
{
|
|
// Retrieve the SketckUp component instance layer.
|
|
SULayerRef SComponentInstanceLayerRef = SU_INVALID;
|
|
SUDrawingElementGetLayer(SUComponentInstanceToDrawingElement(InComponentInstanceRef), &SComponentInstanceLayerRef); // we can ignore the returned SU_RESULT
|
|
|
|
// Retrieve the SketchUp component instance layer name.
|
|
FString SComponentInstanceLayerName;
|
|
SComponentInstanceLayerName = SuGetString(SULayerGetName, SComponentInstanceLayerRef);
|
|
|
|
// Return the effective layer.
|
|
return SComponentInstanceLayerName.Equals(TEXT("Layer0")) ? InInheritedLayerRef : SComponentInstanceLayerRef;
|
|
}
|
|
|
|
FComponentDefinitionIDType DatasmithSketchUpUtils::GetComponentID(
|
|
SUComponentDefinitionRef InComponentDefinitionRef
|
|
)
|
|
{
|
|
return GetEntityID(SUComponentDefinitionToEntity(InComponentDefinitionRef));
|
|
}
|
|
|
|
FComponentInstanceIDType DatasmithSketchUpUtils::GetComponentInstanceID(
|
|
SUComponentInstanceRef InComponentInstanceRef
|
|
)
|
|
{
|
|
return GetEntityID(SUComponentInstanceToEntity(InComponentInstanceRef));
|
|
}
|
|
|
|
FComponentInstanceIDType DatasmithSketchUpUtils::GetGroupID(
|
|
SUGroupRef InGroupRef
|
|
)
|
|
{
|
|
return GetEntityID(SUGroupToEntity(InGroupRef));
|
|
}
|
|
|
|
|
|
|
|
int64 DatasmithSketchUpUtils::GetComponentPID(
|
|
SUComponentInstanceRef InComponentInstanceRef
|
|
)
|
|
{
|
|
// Get the SketckUp component instance persistent ID.
|
|
int64 SPersistentID = 0;
|
|
SUEntityGetPersistentID(SUComponentInstanceToEntity(InComponentInstanceRef), &SPersistentID); // we can ignore the returned SU_RESULT
|
|
|
|
return SPersistentID;
|
|
}
|
|
|
|
FEntityIDType DatasmithSketchUpUtils::GetSceneID(
|
|
SUSceneRef InSceneRef
|
|
)
|
|
{
|
|
return GetEntityID(SUSceneToEntity(InSceneRef));;
|
|
}
|
|
|
|
FEntityIDType DatasmithSketchUpUtils::GetMaterialID(
|
|
SUMaterialRef InMaterialRef
|
|
)
|
|
{
|
|
return GetEntityID(SUMaterialToEntity(InMaterialRef));
|
|
}
|
|
|
|
|
|
int32 DatasmithSketchUpUtils::GetFaceID(
|
|
SUFaceRef InFaceRef
|
|
)
|
|
{
|
|
// Get the SketckUp face ID.
|
|
int32 SFaceID = 0;
|
|
SUEntityGetID(SUFaceToEntity(InFaceRef), &SFaceID); // we can ignore the returned SU_RESULT
|
|
|
|
return SFaceID;
|
|
}
|
|
|
|
int32 DatasmithSketchUpUtils::GetEdgeID(
|
|
SUEdgeRef InEdgeRef
|
|
)
|
|
{
|
|
// Get the SketckUp edge ID.
|
|
int32 SEdgeID = 0;
|
|
SUEntityGetID(SUEdgeToEntity(InEdgeRef), &SEdgeID); // we can ignore the returned SU_RESULT
|
|
|
|
return SEdgeID;
|
|
}
|
|
|
|
bool DatasmithSketchUpUtils::IsVisible(
|
|
SUComponentInstanceRef InSComponentInstanceRef,
|
|
SULayerRef InSEffectiveLayerRef
|
|
)
|
|
{
|
|
// Get the flag indicating whether or not the SketchUp component instance is hidden.
|
|
bool bSComponentInstanceHidden = false;
|
|
SUDrawingElementGetHidden(SUComponentInstanceToDrawingElement(InSComponentInstanceRef), &bSComponentInstanceHidden); // we can ignore the returned SU_RESULT
|
|
|
|
// Get the flag indicating whether or not the SketchUp component instance effective layer is visible.
|
|
bool bSEffectiveLayerVisible = true;
|
|
SULayerGetVisibility(InSEffectiveLayerRef, &bSEffectiveLayerVisible); // we can ignore the returned SU_RESULT
|
|
|
|
return (!bSComponentInstanceHidden && bSEffectiveLayerVisible);
|
|
}
|
|
|
|
bool DatasmithSketchUpUtils::IsVisible(
|
|
SUFaceRef InFaceRef
|
|
)
|
|
{
|
|
// Get the flag indicating whether or not the SketchUp face is hidden.
|
|
bool bFaceHidden = false;
|
|
SUDrawingElementGetHidden(SUFaceToDrawingElement(InFaceRef), &bFaceHidden); // we can ignore the returned SU_RESULT
|
|
|
|
// Retrieve the SketckUp face layer.
|
|
SULayerRef SFaceLayerRef = SU_INVALID;
|
|
SUDrawingElementGetLayer(SUFaceToDrawingElement(InFaceRef), &SFaceLayerRef); // we can ignore the returned SU_RESULT
|
|
|
|
// Retrieve the SketchUp face layer name.
|
|
FString SFaceLayerName = SuGetString(SULayerGetName, SFaceLayerRef);
|
|
|
|
// Get the flag indicating whether or not the SketchUp face effective layer is visible.
|
|
bool bSFaceEffectiveLayerVisible = true;
|
|
SULayerGetVisibility(SFaceLayerRef, &bSFaceEffectiveLayerVisible); // we can ignore the returned SU_RESULT
|
|
|
|
return (!bFaceHidden && bSFaceEffectiveLayerVisible);
|
|
}
|
|
|
|
SUMaterialRef DatasmithSketchUpUtils::GetMaterial(
|
|
SUComponentInstanceRef InComponentInstanceRef
|
|
)
|
|
{
|
|
// Retrieve the SketckUp drawing element material.
|
|
SUMaterialRef SMaterialRef = SU_INVALID;
|
|
SUDrawingElementGetMaterial(SUComponentInstanceToDrawingElement(InComponentInstanceRef), &SMaterialRef); // we can ignore the returned SU_RESULT
|
|
|
|
return SMaterialRef;
|
|
}
|
|
|
|
void DatasmithSketchUpUtils::SetActorTransform(
|
|
TSharedPtr<IDatasmithActorElement> InActorElement,
|
|
SUTransformation const& InWorldTransform
|
|
)
|
|
{
|
|
// We use Imath::extractAndRemoveScalingAndShear() because FMatrix::ExtractScaling() is deemed unreliable.
|
|
|
|
// Set up a scaling and rotation matrix.
|
|
auto& SMatrix = InWorldTransform.values;
|
|
Imath::Matrix44<float> Matrix(float(SMatrix[0]), float(SMatrix[1]), float(SMatrix[2]), 0.0,
|
|
float(SMatrix[4]), float(SMatrix[5]), float(SMatrix[6]), 0.0,
|
|
float(SMatrix[8]), float(SMatrix[9]), float(SMatrix[10]), 0.0,
|
|
0.0, 0.0, 0.0, 1.0);
|
|
|
|
// Remove any scaling from the matrix and get the scale vector that was initially present.
|
|
Imath::Vec3<float> Scale;
|
|
Imath::Vec3<float> Shear;
|
|
bool bExtracted = Imath::extractAndRemoveScalingAndShear<float>(Matrix, Scale, Shear, false);
|
|
|
|
if (!bExtracted)
|
|
{
|
|
ADD_SUMMARY_LINE(TEXT("WARNING: Actor %ls (%ls) has some zero scaling"), InActorElement->GetName(), InActorElement->GetLabel());
|
|
return;
|
|
}
|
|
|
|
if (SMatrix[15] != 1.0)
|
|
{
|
|
// Apply the extra SketchUp uniform scaling factor.
|
|
Scale *= float(SMatrix[15]);
|
|
}
|
|
|
|
// Initialize a rotation quaternion with the rotation matrix.
|
|
Imath::Quat<float> Quaternion = Imath::extractQuat<float>(Matrix);
|
|
|
|
// Convert the SketchUp right-handed Z-up coordinate rotation into an Unreal left-handed Z-up coordinate rotation.
|
|
// This is done by inverting the X and Z components of the quaternion to mirror the quaternion on the XZ-plane.
|
|
Quaternion.v.x = -Quaternion.v.x;
|
|
Quaternion.v.z = -Quaternion.v.z;
|
|
Quaternion.normalize();
|
|
|
|
// Make sure Unreal will be able to handle the rotation quaternion.
|
|
float Angle = Quaternion.angle();
|
|
Imath::Vec3<float> Axis = Quaternion.axis();
|
|
FQuat Rotation(FVector(Axis.x, Axis.y, Axis.z), Angle);
|
|
|
|
ensure(Rotation.IsNormalized());
|
|
|
|
// Convert the SketchUp right-handed Z-up coordinate translation into an Unreal left-handed Z-up coordinate translation.
|
|
// To avoid perturbating X, which is forward in Unreal, the handedness conversion is done by flipping the side vector Y.
|
|
// SketchUp uses inches as internal system unit for all 3D coordinates in the model while Unreal uses centimeters.
|
|
|
|
FVector3f Translation = DatasmithSketchUpUtils::FromSketchUp::ConvertPosition(SMatrix[12], SMatrix[13], SMatrix[14]);
|
|
|
|
// Set the world transform of the Datasmith actor.
|
|
InActorElement->SetTranslation(Translation.X, Translation.Y, Translation.Z, false);
|
|
InActorElement->SetRotation((float)Rotation.X, (float)Rotation.Y, (float)Rotation.Z, (float)Rotation.W, false);
|
|
InActorElement->SetScale(Scale.x, Scale.y, Scale.z, false);
|
|
}
|
|
|
|
SUTransformation DatasmithSketchUpUtils::GetComponentInstanceTransform(SUComponentInstanceRef InComponentInstanceRef, SUTransformation const& InWorldTransform)
|
|
{
|
|
// Get the SketchUp component instance transform.
|
|
SUTransformation SComponentInstanceTransform;
|
|
SUComponentInstanceGetTransform(InComponentInstanceRef, &SComponentInstanceTransform); // we can ignore the returned SU_RESULT
|
|
|
|
// Compute the world transform of the SketchUp component instance.
|
|
SUTransformation SComponentInstanceWorldTransform;
|
|
SUTransformationMultiply(&InWorldTransform, &SComponentInstanceTransform, &SComponentInstanceWorldTransform); // we can ignore the returned SU_RESULT
|
|
return SComponentInstanceWorldTransform;
|
|
}
|
|
|