diff --git a/Plugin~/Src/mscore/msServerAPI.cpp b/Plugin~/Src/mscore/msServerAPI.cpp index 26fdf9501..2c049c081 100644 --- a/Plugin~/Src/mscore/msServerAPI.cpp +++ b/Plugin~/Src/mscore/msServerAPI.cpp @@ -341,7 +341,7 @@ msAPI void msServerSendCurve(ms::Server* server, const char* path, int splineInd auto curve = server->getOrCreatePendingEntity(path); - if (curve->splines.size() <= splineIndex) { + while (curve->splines.size() <= splineIndex) { curve->splines.push_back(ms::CurveSpline::create()); } diff --git a/Runtime/Plugins/x86_64/mscore.dll b/Runtime/Plugins/x86_64/mscore.dll index 69fa7cfca..760166c14 100644 Binary files a/Runtime/Plugins/x86_64/mscore.dll and b/Runtime/Plugins/x86_64/mscore.dll differ diff --git a/Runtime/Scripts/BaseMeshSync.Modifiers.cs b/Runtime/Scripts/BaseMeshSync.Modifiers.cs index 738ebd639..579c78e31 100644 --- a/Runtime/Scripts/BaseMeshSync.Modifiers.cs +++ b/Runtime/Scripts/BaseMeshSync.Modifiers.cs @@ -417,66 +417,90 @@ private void UpdateProperties(SceneData scene) { private EntityRecord UpdateCurveEntity(CurvesData data, MeshSyncPlayerConfig config) { #if AT_USE_SPLINES - lock (splineLock) - { - TransformData dtrans = data.transform; - EntityRecord rec = UpdateTransformEntity(dtrans, config); + lock (splineLock) { + TransformData dtrans = data.transform; + EntityRecord rec = UpdateTransformEntity(dtrans, config); + + GameObject go = rec.go; + Transform trans = go.transform; - GameObject go = rec.go; - Transform trans = go.transform; + SplineContainer splineContainer = rec.splineContainer; - SplineContainer splineContainer = rec.splineContainer; - - if (splineContainer == null) - { - splineContainer = rec.splineContainer = Misc.GetOrAddComponent(trans.gameObject); - } + if (splineContainer == null) { + splineContainer = rec.splineContainer = Misc.GetOrAddComponent(trans.gameObject); + } - float3[] cos = null; - float3[] handles_left = null; - float3[] handles_right = null; + float3[] cos = null; + float3[] handles_left = null; + float3[] handles_right = null; - var numSplines = data.numSplines; + var numSplines = data.numSplines; - Spline.Changed -= SplineChanged; + Spline.Changed -= SplineChanged; - var newSplines = new List(); + // Try to reuse the same splines if the number of splines and knots has not changed: + bool useNewSplines = splineContainer.Splines.Count != numSplines; + if (!useNewSplines) { + for (int index = 0; index < numSplines; index++) { + if (splineContainer.Splines[index].Count != data.GetNumSplinePoints(index)) { + useNewSplines = true; + break; + } + } + } + + var newSplines = new List(); - for (int index = 0; index < numSplines; index++) - { - var spline = new Spline(); + for (int index = 0; index < numSplines; index++) { + Spline spline; + if (useNewSplines) { + spline = new Spline(); newSplines.Add(spline); + } + else { + spline = splineContainer.Splines[index]; + } - spline.Closed = data.IsSplineClosed(index); + // Need to be in this mode to be consistent with blender: + spline.SetTangentMode(TangentMode.Broken); - var numPoints = data.GetNumSplinePoints(index); - m_tmpFloat3.Resize(numPoints); + spline.Closed = data.IsSplineClosed(index); - data.ReadSplineCos(index, m_tmpFloat3); - m_tmpFloat3.CopyTo(ref cos); + var numPoints = data.GetNumSplinePoints(index); + m_tmpFloat3.Resize(numPoints); - data.ReadSplineHandlesLeft(index, m_tmpFloat3); - m_tmpFloat3.CopyTo(ref handles_left); + data.ReadSplineCos(index, m_tmpFloat3); + m_tmpFloat3.CopyTo(ref cos); - data.ReadSplineHandlesRight(index, m_tmpFloat3); - m_tmpFloat3.CopyTo(ref handles_right); + data.ReadSplineHandlesLeft(index, m_tmpFloat3); + m_tmpFloat3.CopyTo(ref handles_left); - for (int pointIndex = 0; pointIndex < cos.Length; pointIndex++) - { - var co = cos[pointIndex]; + data.ReadSplineHandlesRight(index, m_tmpFloat3); + m_tmpFloat3.CopyTo(ref handles_right); - var knot = new BezierKnot(co, handles_left[pointIndex] - co, handles_right[pointIndex] - co, Quaternion.identity); + for (int pointIndex = 0; pointIndex < cos.Length; pointIndex++) { + var co = cos[pointIndex]; + var knot = new BezierKnot(co, handles_left[pointIndex] - co, handles_right[pointIndex] - co, + Quaternion.identity); + + if (useNewSplines) { spline.Add(knot); } + else { + spline.SetKnot(pointIndex, knot); + } } + } + if (useNewSplines) { splineContainer.Splines = newSplines; - - Spline.Changed += SplineChanged; - - return rec; } + + Spline.Changed += SplineChanged; + + return rec; + } #else // If the curve was exported as a mesh before, delete this now, as it's handled as a curve: TransformData dtrans = data.transform; @@ -491,6 +515,7 @@ private EntityRecord UpdateCurveEntity(CurvesData data, MeshSyncPlayerConfig con #if AT_USE_SPLINES protected virtual void SplineChanged(Spline spline, int arg2, SplineModification arg3) { + // Overriden in Server. } #endif } diff --git a/Runtime/Scripts/msNetworkAPI.cs b/Runtime/Scripts/msNetworkAPI.cs index 8abfd0726..c11d2a425 100644 --- a/Runtime/Scripts/msNetworkAPI.cs +++ b/Runtime/Scripts/msNetworkAPI.cs @@ -214,7 +214,7 @@ public string screenshotPath { #if AT_USE_SPLINES - public void SendCurve(string path, int splineIndex, int knotCount, bool closed, float3[] cos, float3[] handlesLeft, float3[] handlesRight) + public void SendCurve(string path, int splineIndex, int knotCount, bool closed, float3[] cos, float3[] handlesLeft, float3[] handlesRight) { msServerSendCurve(self, path, splineIndex, knotCount, closed, cos, handlesLeft, handlesRight); }