From 3293eeb0bf228915c802fc2080f2971ade0cd3f6 Mon Sep 17 00:00:00 2001 From: JulioJerez Date: Mon, 21 Oct 2024 21:49:35 -0700 Subject: [PATCH] more work on plugin (wip) --- .../Content/NewtonTransparentMaterial.uasset | Bin 10859 -> 10840 bytes .../newton/Source/newton/Private/Newton.cpp | 12 +- .../Source/newton/Private/NewtonCollision.cpp | 13 +- .../Source/newton/Private/NewtonCollision.h | 1 + .../NewtonCollisionConvexApproximate.cpp | 336 ++++++++++++++++++ .../NewtonCollisionConvexApproximate.h | 53 +++ .../Private/NewtonCollisionConvexHull.cpp | 17 - .../Private/NewtonCollisionConvexHull.h | 5 +- .../Source/newton/Private/NewtonRigidBody.cpp | 182 ++-------- .../Source/newton/Private/NewtonRigidBody.h | 26 -- .../newton/Source/newton/Public/Newton.h | 23 +- .../Source/newton/Public/NewtonCommons.h | 40 +++ 12 files changed, 487 insertions(+), 221 deletions(-) create mode 100644 newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.cpp create mode 100644 newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.h create mode 100644 newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/NewtonCommons.h diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Content/NewtonTransparentMaterial.uasset b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Content/NewtonTransparentMaterial.uasset index 0651ddbaf887ad816959802de5a15c2238b9b156..6f1c44b68ed4fd70fd2ffba4d8dc35c776d0eda9 100644 GIT binary patch delta 2672 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 delta 2696 zcmai$YgAL&701sFPf=iWf+CTigE5avhgx3p2$>l#k06kcxH^NY<52A4v9wHQfe4tn zu|8&u11LA7DwU+sK(LGDAfdHtM9T7kxJC#mQmkPZbqXRx6o|rr-6x1M_Dl2W+?##& z*=O(l|Lxl+ACVuqMC2SbtC(plgy{EIUOac>>!ey6I-38Ns5*Kpv183%_#;w)-uS(Q zUrr!GAH&<2<{?6~n2{4mzsF_MkGY<-#5;*m#D>Rp^c7h8^69o9Kl;dOH+ucLC3L7y zlG`L7HqwLK6||1;O0Qn+N$Y%)h~G31`+UiuTFZsUgYJbrLi}@zfomsI>9M&mB9JK+ zd1-gc|LLU|lt~y;l1X^OD>t#WP`*W=XcH|?Avq|KYx{w38WuVRQ+14!LHJ>4ZhTte zs+N){c(z9>KkM)&MQ*V3ZK>2=keNC0?jYzNJF-m!QrPrak z@rHcv%rzwoT)7^d?U}6a37%;!r=pe1k8|(U_pF^U{g}mNiopyCL548V?e%5d4=YQH zLeMWe*%LLYKY3OCnYxrq>}elOJf>(cNnEZBbQqpqZ_vkI_}ny&ax`(np8vX0-?JT@ zqsUuAYsnY=H6)7tMfScf%ZqH=38<23!L5Qrp~UZl@?+aaQ}xO~SbZvK=b95U>i^9| zwI4c8b+YTUBuYs8#*KSSVWjP!Gy737ocrED+bmx_G&hN2z@&10S$Y(FRqqMqzwPq(6DnrY< zTnlBFnnx4Cif9oix;KMuRH$?x_$4E6u@7Psm+iP#wFz@1SEC?N1a3dx)7w-FkF_x# z3YVPv%)`w7#G!M;)jRTa)?Qo9Lv23V$+WMZR>d}tioBtis6jTSQW?@O@Ca*$RJ63i z(dxA`I^FzSmW%2W9hH{XeLynNotcCBhHYafR7x*sfprGG3JIVE3`VUz0Q^ct%Mu+_ zp0#hzem`C3TG!#oo9GaZqD1Hr7uxQn(WhS$WFnrvN*UZ|Q|~AcYvxxE*ChC67A3qy zySrQ*XB$~}di8oGyZ!e!pCvb$`Q5m;x?H!iEY%4;n(wqA&@P63TV~|hMv_EHNm+Y) zYnseFr|&PasnU$c1>!0dN*x(V7$1>BP+*(ob|}~o;k;%I%TiuGoY5^>A~SvRB(L~v zG8uw6n;>Xw z3v2eiGnoi>UR|;y zmk|vIt%8uN1F(7-7TEa#nbM@-^<7pI7#z|j1%H2aR3MKb&OBUJYAGnlL_r^68a6Ns zR>oR@YeADy5xN|uZ zIdknKSif(mNGwIaeT^ue$}w%D@RUc6$AkfJhJ-L$UU76Dw^OG&g;sP3FuHlM>A}>z zkt*j{+z>X8R%P-C0r-9cQR!5#c5@|6`DrBHq1~kgp}v~VA-|&V2_} zAO^g^U-vvYPo%1sLskN-*kyk_lMSSVsiCkrhsCZ7yK#WW43?JJ^<7HY=)qi1rtL zBN?S12d2IC&VL5)sMCy_jLUPwM{7N%=)tuso3q(+7e;&x-NqI*zgQFQv83 FindConvexHull(long long hash) const + TSharedPtr FindConvexHull(long long hash) const { return m_convexVhacdCache.Find(hash); } @@ -110,7 +110,7 @@ class FnewtonModule::ResourceCache m_shapeCache.Insert(shape, hash); } - void AddConvexHull(const TSharedPtr& hull, long long hash) + void AddConvexHull(const TSharedPtr& hull, long long hash) { m_convexVhacdCache.Insert(hull, hash); } @@ -134,7 +134,7 @@ class FnewtonModule::ResourceCache } ndTree m_shapeCache; - Cache m_convexVhacdCache; + Cache m_convexVhacdCache; Cache m_visualMeshCache; }; @@ -258,12 +258,12 @@ void FnewtonModule::AddShape(ndShape* shape, long long hash) m_resourceCache->AddShape(shape, hash); } -TSharedPtr FnewtonModule::FindConvexHull(long long hash) const +TSharedPtr FnewtonModule::FindConvexHull(long long hash) const { return m_resourceCache->FindConvexHull(hash); } -void FnewtonModule::AddConvexHull(const TSharedPtr& hull, long long hash) +void FnewtonModule::AddConvexHull(const TSharedPtr& hull, long long hash) { m_resourceCache->AddConvexHull(hull, hash); } diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.cpp b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.cpp index 7c3c54e4d..a1663792d 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.cpp +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.cpp @@ -28,7 +28,7 @@ class UNewtonCollision::PolygonizeMesh : public ndShapeDebugNotify ndArray triangles; ndTriangulatePolygon(&m_points[baseIndex], vertexCount, triangles); - //check((vertexCount - 2) == ndInt32 (triangles.GetCount() / 3)); + check((vertexCount - 2) == ndInt32 (triangles.GetCount() / 3)); for (ndInt32 i = 0; i < ndInt32(triangles.GetCount()); i += 3) { @@ -92,12 +92,13 @@ UNewtonCollision::UNewtonCollision() m_visualMesh = TSharedPtr(nullptr); ConstructorHelpers::FObjectFinder TexObj(TEXT("/newton/NewtonTransparentMaterial")); - TObjectPtr debugMaterial(Cast(TexObj.Object)); - debugMaterial->OpacityMaskClipValue = 0.0f; + m_debugMaterial = Cast(TexObj.Object); + m_debugMaterial->OpacityMaskClipValue = 0.0f; - UMaterialInstanceDynamic* const debugMaterialInstance = UMaterialInstanceDynamic::Create(debugMaterial, nullptr); - debugMaterialInstance->OpacityMaskClipValue = 0.1f; - SetMaterial(0, debugMaterialInstance); + //UMaterialInstanceDynamic* const debugMaterialInstance = UMaterialInstanceDynamic::Create(m_debugMaterial, nullptr); + //debugMaterialInstance->OpacityMaskClipValue = 0.0f; + //SetMaterial(0, debugMaterialInstance); + SetMaterial(0, m_debugMaterial); } void UNewtonCollision::OnRegister() diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.h b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.h index 47098e926..63d7f9467 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.h +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollision.h @@ -55,6 +55,7 @@ class UNewtonCollision : public UDynamicMeshComponent //public: long long m_hash; ndShape* m_shape; + TObjectPtr m_debugMaterial; TSharedPtr m_visualMesh; bool m_propertyChanged; bool m_showDebug; diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.cpp b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.cpp new file mode 100644 index 000000000..994edfb51 --- /dev/null +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.cpp @@ -0,0 +1,336 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "NewtonCollisionConvexApproximate.h" + +#include "Newton.h" +#include "NewtonRigidBody.h" +#include "NewtonSceneActor.h" +#include "ThirdParty/newtonLibrary/Public/dNewton/ndNewton.h" +#include "ThirdParty/newtonLibrary/Public/thirdParty/ndConvexApproximation.h" + +//#define SHOW_VHACD_PROGRESS_BAR + +class UNewtonCollisionConvexApproximate::ConvexVhacdGenerator : public ndConvexApproximation +{ + public: + ConvexVhacdGenerator(ndInt32 maxConvexes, bool quality) + :ndConvexApproximation(maxConvexes, quality) + ,m_progressBar(nullptr) + ,m_acc(0.0f) + { + #ifdef SHOW_VHACD_PROGRESS_BAR + // for some reason the progress bar invalidate some UClasses + // I need to report this some day to unreal. + // for now just do not report progress. + m_progressBar = new FScopedSlowTask(100.0f, NSLOCTEXT("Newton", "Newton", "Generation Convex Approximation")); + m_progressBar->MakeDialog(); + #endif + } + + ~ConvexVhacdGenerator() + { + if (m_progressBar) + { + delete m_progressBar; + m_progressBar = nullptr; + } + } + + virtual void ShowProgress() override + { + if (m_progressBar) + { + m_acc += 1.0f; + if (m_acc < 99.0f) + { + m_progressBar->EnterProgressFrame(); + } + } + } + + FScopedSlowTask* m_progressBar; + float m_acc; +}; + +UNewtonCollisionConvexApproximate::UNewtonCollisionConvexApproximate() + :Super() +{ + Generate = false; + m_generateFlipFlop = false; + HighResolution = false; + MaxConvexes = 16; + Tolerance = 0.0f; + MaxVertexPerConvex = 32; +} + +void UNewtonCollisionConvexApproximate::Serialize(FArchive& ar) +{ + Super::Serialize(ar); + + // this actually sucks big time in unreal + //ar.UsingCustomVersion(FnewtonModule::m_guiID); + //int version = ar.CustomVer(FnewtonModule::m_guiID); + if (ar.IsSaving()) + { + int numOfConvex = m_convexHullSet ? m_convexHullSet->Num() : 0; + ar << numOfConvex; + for (int j = 0; j < numOfConvex; ++j) + { + ndHullPoints& hull = *(*m_convexHullSet)[j]; + ar << hull; + } + } + else + { + FnewtonModule* const plugin = FnewtonModule::GetPlugin(); + check(plugin); + long long meshHash = CalculateStaticMeshHash(); + TSharedPtr serializedSet(plugin->FindConvexHull(m_hash)); + if (serializedSet == nullptr) + { + int numOfConvex = m_convexHullSet ? m_convexHullSet->Num() : 0; + ar << numOfConvex; + if (numOfConvex) + { + TSharedPtr convexHullSet(new ndConvexHullSet); + for (int j = 0; j < numOfConvex; ++j) + { + ndHullPoints* const newHull = new ndHullPoints; + ndHullPoints& hull = *newHull; + ar << hull; + convexHullSet->Push(newHull); + } + m_convexHullSet = convexHullSet; + plugin->AddConvexHull(convexHullSet, meshHash); + } + + } + else + { + int numOfConvex = m_convexHullSet ? m_convexHullSet->Num() : 0; + ar << numOfConvex; + if (numOfConvex) + { + ndConvexHullSet convexHullSet; + for (int j = 0; j < numOfConvex; ++j) + { + ndHullPoints* const newHull = new ndHullPoints; + ndHullPoints& hull = *newHull; + ar << hull; + convexHullSet.Push(newHull); + } + } + } + } +} + +ndConvexHullSet* UNewtonCollisionConvexApproximate::CreateConvexApproximationShapes() const +{ + const UStaticMeshComponent* const staticComponent = Cast(GetAttachParent()); + if (!staticComponent) + { + check(0); + return nullptr; + } + + ConvexVhacdGenerator* const vhacdHullSet = new ConvexVhacdGenerator(MaxConvexes, HighResolution); + vhacdHullSet->m_tolerance = 1.0e-3f + Tolerance * 0.1f; + vhacdHullSet->m_maxPointPerHull = MaxVertexPerConvex; + + const UStaticMesh* const staticMesh = staticComponent->GetStaticMesh().Get(); + check(staticMesh); + const FStaticMeshRenderData* const renderData = staticMesh->GetRenderData(); + check(renderData); + const FStaticMeshLODResourcesArray& renderResource = renderData->LODResources; + + const FVector uScale(GetComponentTransform().GetScale3D()); + const ndVector scale(ndFloat32(uScale.X), ndFloat32(uScale.Y), ndFloat32(uScale.Z), ndFloat32(0.0f)); + const ndVector bakedScale(scale.Scale(UNREAL_INV_UNIT_SYSTEM)); + + const FStaticMeshLODResources& renderLOD = renderResource[0]; + const FStaticMeshVertexBuffers& staticMeshVertexBuffer = renderLOD.VertexBuffers;; + const FPositionVertexBuffer& positBuffer = staticMeshVertexBuffer.PositionVertexBuffer; + + ndHullInputMesh& inputMesh = vhacdHullSet->m_inputMesh; + for (ndInt32 i = 0; i < ndInt32(positBuffer.GetNumVertices()); ++i) + { + ndHullPoint q; + const FVector3f p(positBuffer.VertexPosition(i)); + + q.m_x = ndReal(p.X * bakedScale.m_x); + q.m_y = ndReal(p.Y * bakedScale.m_y); + q.m_z = ndReal(p.Z * bakedScale.m_z); + inputMesh.m_points.PushBack(q); + } + + const FRawStaticIndexBuffer& indexBuffer = renderLOD.IndexBuffer; + for (ndInt32 i = 0; i < ndInt32(indexBuffer.GetNumIndices()); i += 3) + { + ndHullInputMesh::ndFace face; + face.m_i0 = indexBuffer.GetIndex(i + 0); + face.m_i1 = indexBuffer.GetIndex(i + 1); + face.m_i2 = indexBuffer.GetIndex(i + 2); + check(face.m_i0 != face.m_i1); + check(face.m_i0 != face.m_i2); + check(face.m_i1 != face.m_i2); + inputMesh.m_faces.PushBack(face); + } + + vhacdHullSet->Execute(); + + ndConvexHullSet* const hullSet = new ndConvexHullSet; + ndArray& hullArray = vhacdHullSet->m_ouputHulls; + for (ndInt32 i = hullArray.GetCount() - 1; i >= 0; --i) + //for (ndInt32 i = 4; i < 6; ++i) + { + ndHullPoints* const pointsSet = new ndHullPoints; + const ndHullOutput* const convexHull = hullArray[i]; + + ndHullPoints& dstPoints = *pointsSet; + const ndArray& srcPoints = *convexHull; + for (ndInt32 j = ndInt32(srcPoints.GetCount()) - 1; j >= 0; --j) + { + FVector3f p(srcPoints[j].m_x, srcPoints[j].m_y, srcPoints[j].m_z); + dstPoints.Push(p); + } + hullSet->Push(pointsSet); + } + + delete vhacdHullSet; + return hullSet; +} + +long long UNewtonCollisionConvexApproximate::CalculateHash() const +{ + long long hash = ndCRC64(ndShapeCompound::StaticClassName(), strlen(ndShapeConvexHull::StaticClassName()), 0); + if (m_convexHullSet && m_convexHullSet->Num()) + { + for (ndInt32 i = 0; i < m_convexHullSet->Num(); ++i) + { + const ndHullPoints& hull = *(*m_convexHullSet)[i]; + const FVector3f* const vexterBuffer = &hull[0]; + hash = ndCRC64(vexterBuffer, hull.Num() * sizeof(FVector3f), hash); + } + } + return hash; +} + +ndShape* UNewtonCollisionConvexApproximate::CreateShape() const +{ + if (m_convexHullSet && m_convexHullSet->Num()) + { + //const FVector uScale(GetComponentTransform().GetScale3D()); + //const ndVector scale(ndFloat32(1.0f / uScale.X), ndFloat32(1.0f / uScale.Y), ndFloat32(1.0f / uScale.Z), ndFloat32(0.0f)); + + ndShapeCompound* const compound = new ndShapeCompound(); + compound->BeginAddRemove(); + for (ndInt32 i = m_convexHullSet->Num() - 1; i >= 0; --i) + { + const ndHullPoints& hullPoints = *((*m_convexHullSet)[i]); + const FVector3f* const vexterBuffer = &hullPoints[0]; + ndShape* const shape = new ndShapeConvexHull(hullPoints.Num(), sizeof(FVector3f), Tolerance, &vexterBuffer[0].X); + ndShapeInstance* const subShape = new ndShapeInstance(shape); + //new ndShapeConvexHull(hullPoints, sizeof(ndVector), Tolerance, &points[0].m_x, MaxVertexCount); + //subShape->SetScale(scale); + compound->AddCollision(subShape); + delete subShape; + } + compound->EndAddRemove(); + return compound; + } + return new ndShapeNull(); +} + +void UNewtonCollisionConvexApproximate::InitStaticMeshCompoment(const USceneComponent* const meshComponent) +{ + check(0); +} + +long long UNewtonCollisionConvexApproximate::CalculateStaticMeshHash() const +{ + long long hash = ndCRC64(ndShapeCompound::StaticClassName(), strlen(ndShapeConvexHull::StaticClassName()), 0); + const UStaticMeshComponent* const staticComponent = Cast(GetAttachParent()); + if (staticComponent) + { + ConvexVhacdGenerator* const convexHullSet = new ConvexVhacdGenerator(MaxConvexes, HighResolution); + convexHullSet->m_tolerance = 1.0e-3f + Tolerance * 0.1f; + convexHullSet->m_maxPointPerHull = MaxVertexPerConvex; + + const UStaticMesh* const staticMesh = staticComponent->GetStaticMesh().Get(); + check(staticMesh); + const FStaticMeshRenderData* const renderData = staticMesh->GetRenderData(); + check(renderData); + const FStaticMeshLODResourcesArray& renderResource = renderData->LODResources; + + //const FVector uScale(GetComponentTransform().GetScale3D()); + //const ndVector scale(ndFloat32(uScale.X), ndFloat32(uScale.Y), ndFloat32(uScale.Z), ndFloat32(0.0f)); + //const ndVector bakedScale(scale.Scale(UNREAL_INV_UNIT_SYSTEM)); + + const FStaticMeshLODResources& renderLOD = renderResource[0]; + const FStaticMeshVertexBuffers& staticMeshVertexBuffer = renderLOD.VertexBuffers;; + const FPositionVertexBuffer& positBuffer = staticMeshVertexBuffer.PositionVertexBuffer; + for (ndInt32 i = 0; i < ndInt32(positBuffer.GetNumVertices()); ++i) + { + const FVector3f p(positBuffer.VertexPosition(i)); + hash = ndCRC64(&p, sizeof(FVector3f), hash); + } + const FRawStaticIndexBuffer& indexBuffer = renderLOD.IndexBuffer; + for (ndInt32 i = 0; i < ndInt32(indexBuffer.GetNumIndices()); i += 3) + { + ndInt32 j = indexBuffer.GetIndex(i); + hash = ndCRC64(&j, sizeof(ndInt32), hash); + } + } + return hash; +} + +void UNewtonCollisionConvexApproximate::ApplyPropertyChanges() +{ + FnewtonModule* const plugin = FnewtonModule::GetPlugin(); + check(plugin); + long long meshHash = CalculateStaticMeshHash(); + if (Generate && !m_generateFlipFlop) + { + TSharedPtr convexHullSet (plugin->FindConvexHull(m_hash)); + if (convexHullSet == nullptr) + { + convexHullSet = TSharedPtr(CreateConvexApproximationShapes()); + plugin->AddConvexHull(convexHullSet, meshHash); + } + } + if (m_convexHullSet == nullptr) + { + m_convexHullSet = plugin->FindConvexHull(meshHash); + m_debugVisualIsDirty = true; + } + MarkRenderDynamicDataDirty(); + NotifyMeshUpdated(); + + m_generateFlipFlop = Generate; + Generate = false; + BuildNewtonShape(); + Super::ApplyPropertyChanges(); +} + +ndShapeInstance* UNewtonCollisionConvexApproximate::CreateBodyInstanceShape(const ndMatrix& bodyMatrix) const +{ + ndShapeInstance* const instance = CreateInstanceShape(); + + const ndVector scale(ndFloat32(1.0f)); + const FTransform transform(GetComponentToWorld()); + const ndMatrix matrix(UNewtonRigidBody::ToNewtonMatrix(transform) * bodyMatrix.OrthoInverse()); + + instance->SetScale(scale); + instance->SetLocalMatrix(matrix); + return instance; +} + +ndShapeInstance* UNewtonCollisionConvexApproximate::CreateInstanceShape() const +{ + ndShapeInstance* const instance = new ndShapeInstance(m_shape); + const FVector uScale(GetComponentTransform().GetScale3D()); + const ndVector scale(ndFloat32(1.0f / uScale.X), ndFloat32(1.0f / uScale.Y), ndFloat32(1.0f / uScale.Z), ndFloat32(0.0f)); + instance->SetScale(scale); + return instance; +} \ No newline at end of file diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.h b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.h new file mode 100644 index 000000000..67435145d --- /dev/null +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexApproximate.h @@ -0,0 +1,53 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" + +#include "NewtonCommons.h" +#include "NewtonCollision.h" +#include "NewtonCollisionConvexApproximate.generated.h" + +/** + * + */ +UCLASS(ClassGroup=(NewtonCollision), meta=(BlueprintSpawnableComponent)) +class UNewtonCollisionConvexApproximate : public UNewtonCollision +{ + GENERATED_BODY() + class ConvexVhacdGenerator; + + public: + // Sets default values for this component's properties + UNewtonCollisionConvexApproximate(); + virtual void InitStaticMeshCompoment(const USceneComponent* const meshComponent) override; + + protected: + virtual void ApplyPropertyChanges(); + virtual ndShape* CreateShape() const; + virtual long long CalculateHash() const; + virtual void Serialize(FArchive& ar) override; + virtual ndShapeInstance* CreateInstanceShape() const; + virtual ndShapeInstance* CreateBodyInstanceShape(const ndMatrix& bodyMatrix) const; + + long long CalculateStaticMeshHash() const; + ndConvexHullSet* CreateConvexApproximationShapes() const; + + UPROPERTY(EditAnywhere, Category = Newton) + bool Generate = false; + + UPROPERTY(EditAnywhere, Category = Newton) + bool HighResolution = false; + + UPROPERTY(EditAnywhere, Category = Newton, meta = (ClampMin = 1, ClampMax = 128)) + int MaxVertexPerConvex = 32; + + UPROPERTY(EditAnywhere, Category = Newton, meta = (ClampMin = 1, ClampMax = 128)) + int MaxConvexes = 16; + + UPROPERTY(EditAnywhere, Category = Newton, meta = (ClampMin = 0.0, ClampMax = 1.0)) + float Tolerance = 0.0f; + + bool m_generateFlipFlop; + TSharedPtr m_convexHullSet; +}; diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.cpp b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.cpp index 70f8cd2db..b6e71f29a 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.cpp +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.cpp @@ -19,11 +19,6 @@ UNewtonCollisionConvexHull::UNewtonCollisionConvexHull() void UNewtonCollisionConvexHull::Serialize(FArchive& ar) { Super::Serialize(ar); - - // this actually sucks big time in unreal - //ar.UsingCustomVersion(FnewtonModule::m_guiID); - //int xxxx0 = ar.CustomVer(FnewtonModule::m_guiID); - //ndConvexHullPoints& points = *m_convexHullPoints.Get(); ar << m_convexHullPoints; } @@ -54,18 +49,6 @@ ndShape* UNewtonCollisionConvexHull::CreateShape() const return new ndShapeNull(); } -void UNewtonCollisionConvexHull::InitVhacdConvex(const ndHullOutput* const conveHullMesh) -{ - SetTransform(GetAttachParent()); - - const ndArray& points = *conveHullMesh; - for (ndInt32 i = ndInt32(points.GetCount()) - 1; i >= 0; --i) - { - FVector3f p(points[i].m_x, points[i].m_y, points[i].m_z); - m_convexHullPoints.Push(p); - } -} - void UNewtonCollisionConvexHull::InitStaticMeshCompoment(const USceneComponent* const meshComponent) { SetTransform(meshComponent); diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.h b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.h index a479fb960..ff3fc34b7 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.h +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonCollisionConvexHull.h @@ -20,11 +20,10 @@ class UNewtonCollisionConvexHull : public UNewtonCollision public: // Sets default values for this component's properties UNewtonCollisionConvexHull(); - void InitVhacdConvex(const ndHullOutput* const conveHullMesh); virtual void InitStaticMeshCompoment(const USceneComponent* const meshComponent) override; - + protected: - virtual void Serialize(FArchive& Ar) override; + virtual void Serialize(FArchive& ar) override; virtual void ApplyPropertyChanges(); virtual ndShape* CreateShape() const; diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.cpp b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.cpp index a931e2919..f8d7d75c9 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.cpp +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.cpp @@ -13,11 +13,7 @@ #include "NewtonJoint.h" #include "NewtonCollision.h" #include "NewtonWorldActor.h" -#include "NewtonCollisionConvexHull.h" #include "ThirdParty/newtonLibrary/Public/dNewton/ndNewton.h" -#include "ThirdParty/newtonLibrary/Public/thirdParty/ndConvexApproximation.h" - -#define SHOW_VHACD_PROGRESS_BAR //FLinearColor UNewtonRigidBody::m_awakeColor(1.0f, 0.0f, 0.f); //FLinearColor UNewtonRigidBody::m_sleepingColor(0.0f, 1.0f, 0.f); @@ -25,45 +21,6 @@ FLinearColor UNewtonRigidBody::m_awakeColor(0.0f, 0.5f, 1.0f); FLinearColor UNewtonRigidBody::m_sleepingColor(0.0f, 0.125f, 0.25f); -class UNewtonRigidBody::ConvexVhacdGenerator : public ndConvexApproximation -{ - public: - ConvexVhacdGenerator(ndInt32 maxConvexes, bool quality) - :ndConvexApproximation(maxConvexes, quality) - ,m_progressBar(nullptr) - ,m_acc(0.0f) - { - #ifdef SHOW_VHACD_PROGRESS_BAR - // for some reason the progress bar invalidate some UClasses - // I need to report this some day to unreal. - // for now just do not report progress. - m_progressBar = new FScopedSlowTask(100.0f, NSLOCTEXT("Newton", "Newton", "Generation Convex Approximation")); - m_progressBar->MakeDialog(); - #endif - } - - ~ConvexVhacdGenerator() - { - if (m_progressBar) - { - delete m_progressBar; - m_progressBar = nullptr; - } - } - - virtual void ShowProgress() override - { - m_acc += 1.0f; - if (m_acc < 99.0f) - { - m_progressBar->EnterProgressFrame(); - } - } - - FScopedSlowTask* m_progressBar; - float m_acc; -}; - class UNewtonRigidBody::NotifyCallback : public ndBodyNotify { public: @@ -509,39 +466,39 @@ void UNewtonRigidBody::ApplyPropertyChanges() const FVector inertia(inertiaMatrix[0][0] * scale, inertiaMatrix[1][1] * scale, inertiaMatrix[2][2] * scale); Inertia.PrincipalInertia = inertia * Inertia.PrincipalInertiaScaler; - if (ConvexApproximate.Generate) - { - const AActor* const owner = GetOwner(); - const TArray>& children = GetAttachChildren(); - for (int j = children.Num() - 1; j >= 0; --j) - { - UStaticMeshComponent* const staticMeshComponent = Cast(children[j]); - - if (staticMeshComponent && staticMeshComponent->GetOwner() && staticMeshComponent->GetStaticMesh().Get()) - { - bool hasCollision = false; - const TArray>& childrenComp = staticMeshComponent->GetAttachChildren(); - for (ndInt32 i = childrenComp.Num() - 1; i >= 0; --i) - { - hasCollision = hasCollision || (Cast(childrenComp[i]) ? true : false); - } - - if (hasCollision) - { - UE_LOG(LogTemp, Warning, TEXT("static mesh: %s, has one or more child collision shape alreary. You must delete all the UNewtonCollision children first"), *staticMeshComponent->GetName()); - } - else - { - CreateConvexApproximationShapes(staticMeshComponent); - } - } - } - - ConvexApproximate.Generate = false; - FLevelEditorModule& levelEditor = FModuleManager::LoadModuleChecked("LevelEditor"); - levelEditor.BroadcastComponentsEdited(); - levelEditor.BroadcastRedrawViewports(false); - } + //if (ConvexApproximate.Generate) + //{ + // const AActor* const owner = GetOwner(); + // const TArray>& children = GetAttachChildren(); + // for (int j = children.Num() - 1; j >= 0; --j) + // { + // UStaticMeshComponent* const staticMeshComponent = Cast(children[j]); + // + // if (staticMeshComponent && staticMeshComponent->GetOwner() && staticMeshComponent->GetStaticMesh().Get()) + // { + // bool hasCollision = false; + // const TArray>& childrenComp = staticMeshComponent->GetAttachChildren(); + // for (ndInt32 i = childrenComp.Num() - 1; i >= 0; --i) + // { + // hasCollision = hasCollision || (Cast(childrenComp[i]) ? true : false); + // } + // + // if (hasCollision) + // { + // UE_LOG(LogTemp, Warning, TEXT("static mesh: %s, has one or more child collision shape alreary. You must delete all the UNewtonCollision children first"), *staticMeshComponent->GetName()); + // } + // else + // { + // CreateConvexApproximationShapes(staticMeshComponent); + // } + // } + // } + // + // ConvexApproximate.Generate = false; + // FLevelEditorModule& levelEditor = FModuleManager::LoadModuleChecked("LevelEditor"); + // levelEditor.BroadcastComponentsEdited(); + // levelEditor.BroadcastRedrawViewports(false); + //} } // Called every frame @@ -557,73 +514,6 @@ void UNewtonRigidBody::TickComponent(float DeltaTime, ELevelTick TickType, FActo } } -void UNewtonRigidBody::CreateConvexApproximationShapes(UStaticMeshComponent* const staticComponent) -{ - ConvexVhacdGenerator* const convexHullSet = new ConvexVhacdGenerator(ConvexApproximate.MaxConvexes, ConvexApproximate.HighResolution); - convexHullSet->m_tolerance = 1.0e-3f + ConvexApproximate.Tolerance * 0.1f; - convexHullSet->m_maxPointPerHull = ConvexApproximate.MaxVertexPerConvex; - - const UStaticMesh* const staticMesh = staticComponent->GetStaticMesh().Get(); - check(staticMesh); - const FStaticMeshRenderData* const renderData = staticMesh->GetRenderData(); - check(renderData); - const FStaticMeshLODResourcesArray& renderResource = renderData->LODResources; - - const FVector uScale(GetComponentTransform().GetScale3D()); - const ndVector scale(ndFloat32(uScale.X), ndFloat32(uScale.Y), ndFloat32(uScale.Z), ndFloat32(0.0f)); - const ndVector bakedScale(scale.Scale(UNREAL_INV_UNIT_SYSTEM)); - - const FStaticMeshLODResources& renderLOD = renderResource[0]; - const FStaticMeshVertexBuffers& staticMeshVertexBuffer = renderLOD.VertexBuffers;; - const FPositionVertexBuffer& positBuffer = staticMeshVertexBuffer.PositionVertexBuffer; - - ndHullInputMesh& inputMesh = convexHullSet->m_inputMesh; - for (ndInt32 i = 0; i < ndInt32(positBuffer.GetNumVertices()); ++i) - { - ndHullPoint q; - const FVector3f p(positBuffer.VertexPosition(i)); - - q.m_x = ndReal(p.X * bakedScale.m_x); - q.m_y = ndReal(p.Y * bakedScale.m_y); - q.m_z = ndReal(p.Z * bakedScale.m_z); - inputMesh.m_points.PushBack(q); - } - - const FRawStaticIndexBuffer& indexBuffer = renderLOD.IndexBuffer; - for (ndInt32 i = 0; i < ndInt32(indexBuffer.GetNumIndices()); i += 3) - { - ndHullInputMesh::ndFace face; - face.m_i0 = indexBuffer.GetIndex(i + 0); - face.m_i1 = indexBuffer.GetIndex(i + 1); - face.m_i2 = indexBuffer.GetIndex(i + 2); - check(face.m_i0 != face.m_i1); - check(face.m_i0 != face.m_i2); - check(face.m_i1 != face.m_i2); - inputMesh.m_faces.PushBack(face); - } - - convexHullSet->Execute(); - - AActor* const actor = staticComponent->GetOwner(); - check(actor); - ndArray& hullArray = convexHullSet->m_ouputHulls; - for (ndInt32 i = hullArray.GetCount() - 1; i >= 0; --i) - //for (ndInt32 i = 0; i < 3; ++i) - { - const ndHullOutput* const convexHull = hullArray[i]; - - UNewtonCollisionConvexHull* const childConvex = Cast(actor->AddComponentByClass(UNewtonCollisionConvexHull::StaticClass(), false, FTransform(), true)); - actor->FinishAddComponent(childConvex, false, FTransform()); - actor->AddInstanceComponent(childConvex); - childConvex->AttachToComponent(staticComponent, FAttachmentTransformRules::KeepRelativeTransform); - - childConvex->InitVhacdConvex(convexHull); - childConvex->MarkRenderDynamicDataDirty(); - childConvex->NotifyMeshUpdated(); - } - delete convexHullSet; -} - void UNewtonRigidBody::CreateRigidBody(ANewtonWorldActor* const worldActor, bool overrideAutoSleep) { m_newtonWorld = worldActor; @@ -700,12 +590,18 @@ ndShapeInstance* UNewtonRigidBody::CreateCollision(const ndMatrix& bodyMatrix) c return new ndShapeInstance(new ndShapeNull()); } + if (collisionShapes.GetCount() == 1) + { + return collisionShapes[0]->CreateBodyInstanceShape(bodyMatrix); + } + ndShapeInstance* const compoundInstance = new ndShapeInstance(new ndShapeCompound()); ndShapeCompound* const compound = compoundInstance->GetShape()->GetAsShapeCompound(); compound->BeginAddRemove(); for (ndInt32 i = collisionShapes.GetCount() - 1; i >= 0; --i) { ndShapeInstance* const subShape = collisionShapes[i]->CreateBodyInstanceShape(bodyMatrix); + check(subShape->GetShape()->GetAsShapeCompound() == nullptr); compound->AddCollision(subShape); delete subShape; } diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.h b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.h index 12fb9094e..16738f3b6 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.h +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Private/NewtonRigidBody.h @@ -13,26 +13,6 @@ class ndShapeInstance; class UNewtonCollision; class ANewtonWorldActor; -USTRUCT() -struct FConvexApproximationStruct -{ - GENERATED_BODY(); - - UPROPERTY(EditAnywhere, Category = Newton) - bool Generate = false; - - UPROPERTY(EditAnywhere, Category = Newton) - bool HighResolution = false; - - UPROPERTY(EditAnywhere, Category = Newton, meta = (ClampMin = 1, ClampMax = 128)) - int MaxVertexPerConvex = 32; - - UPROPERTY(EditAnywhere, Category = Newton, meta = (ClampMin = 1, ClampMax = 128)) - int MaxConvexes = 16; - - UPROPERTY(EditAnywhere, Category = Newton, meta = (ClampMin = 0.0, ClampMax = 1.0)) - float Tolerance = 0.0; -}; USTRUCT() struct FInertiaStruct @@ -59,9 +39,7 @@ UCLASS(ClassGroup = Newton, meta=(BlueprintSpawnableComponent), HideCategories = class UNewtonRigidBody : public USceneComponent { GENERATED_BODY() - class NotifyCallback; - class ConvexVhacdGenerator; public: // Sets default values for this component's properties @@ -86,7 +64,6 @@ class UNewtonRigidBody : public USceneComponent void CalculateLocalTransform(); void DrawGizmo(float timestep); void InterpolateTransform(float param); - void CreateConvexApproximationShapes(UStaticMeshComponent* const staticComponent); virtual void ClearDebug(); virtual void ApplyPropertyChanges(); @@ -131,9 +108,6 @@ class UNewtonRigidBody : public USceneComponent UPROPERTY(EditAnywhere, Category = Newton) FVector Gravity; - UPROPERTY(EditAnywhere, Category = Newton) - FConvexApproximationStruct ConvexApproximate; - FVector m_localScale; FVector m_globalScale; FTransform m_localTransform; diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/Newton.h b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/Newton.h index f75bd94ec..366d21a07 100644 --- a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/Newton.h +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/Newton.h @@ -5,29 +5,12 @@ #include "Modules/ModuleManager.h" #include "DynamicMesh/DynamicMesh3.h" #include "Interfaces/IPluginManager.h" - -#define UNREAL_UNIT_SYSTEM ndFloat32 (100.0f) -#define UNREAL_INV_UNIT_SYSTEM ndFloat32 (1.0f / UNREAL_UNIT_SYSTEM) - -class ndShape; -class ANewtonWorldActor; - -template -class ndSharedPtr; - -class ndConvexHullPoints : public TArray -{ - -}; +#include "NewtonCommons.h" class FnewtonModule : public IModuleInterface { class ResourceCache; public: - enum Version - { - m_firstVersion, - }; /** IModuleInterface implementation */ virtual void StartupModule() override; @@ -36,11 +19,11 @@ class FnewtonModule : public IModuleInterface static FnewtonModule* GetPlugin(); ndShape* FindShape(long long hash) const; - TSharedPtr FindConvexHull(long long hash) const; + TSharedPtr FindConvexHull(long long hash) const; TSharedPtr FindDynamicMesh (long long hash) const; void AddShape(ndShape* const shape, long long hash); - void AddConvexHull(const TSharedPtr& hull, long long hash); + void AddConvexHull(const TSharedPtr& hull, long long hash); void AddDynamicMesh(const TSharedPtr& mesh, long long hash); private: diff --git a/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/NewtonCommons.h b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/NewtonCommons.h new file mode 100644 index 000000000..c09da332f --- /dev/null +++ b/newton-4.00/applications/toolsAndWrapers/newtonUnreal/newton/Source/newton/Public/NewtonCommons.h @@ -0,0 +1,40 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + + +#define UNREAL_UNIT_SYSTEM ndFloat32 (100.0f) +#define UNREAL_INV_UNIT_SYSTEM ndFloat32 (1.0f / UNREAL_UNIT_SYSTEM) + +class ndShape; +class ANewtonWorldActor; + +template +class ndSharedPtr; + +enum ndPluginVersion +{ + m_firstVersion, +}; + +class ndHullPoints : public TArray +{ + public: +}; + +class ndConvexHullSet : public TArray +{ + public: + ndConvexHullSet() + :TArray() + { + } + + ~ndConvexHullSet() + { + for (int i = 0; i < Num(); ++i) + { + delete (*this)[i]; + } + } +};