2828using System . Collections . Generic ;
2929using System . Linq ;
3030using UnityEngine ;
31+ using UnityEngine . UIElements ;
3132
3233#if UNITY_SPLINES_INSTALLED
3334
@@ -126,7 +127,7 @@ public override bool CreateInputNodeWithDataUpload(HEU_SessionBase session, HAPI
126127 }
127128
128129 // Get spline data from the input object
129- HEU_InputDataSplines inputSplines = GenerateSplineDataFromGameObject ( inputObject ) ;
130+ HEU_InputDataSplineContainer inputSplines = GenerateSplineDataFromGameObject ( inputObject ) ;
130131 if ( inputSplines == null || inputSplines . _inputSplines == null || inputSplines . _inputSplines . Count ( ) == 0 )
131132 {
132133 HEU_Logger . LogError ( "No valid splines found on input objects." ) ;
@@ -144,7 +145,7 @@ public override bool CreateInputNodeWithDataUpload(HEU_SessionBase session, HAPI
144145 inputNodeID = newNodeID ;
145146
146147 HEU_InputDataSpline inputSpline = inputSplines . _inputSplines [ 0 ] ;
147- if ( ! UploadData ( session , inputNodeID , inputSpline ) )
148+ if ( ! UploadData ( session , inputNodeID , inputSpline , Matrix4x4 . identity ) )
148149 {
149150 if ( ! session . CookNode ( inputNodeID , false ) )
150151 {
@@ -155,21 +156,16 @@ public override bool CreateInputNodeWithDataUpload(HEU_SessionBase session, HAPI
155156 return false ;
156157 }
157158
158- if ( ! session . CookNode ( inputNodeID , false ) )
159- {
160- HEU_Logger . LogError ( "New input node failed to cook!" ) ;
161- return false ;
162- }
163-
159+ // The spline is made up of branching sub-splines.
160+ // Create an input node for each branching spline and object-merge it to the root spline.
164161 bool createMergeNode = inputSplines . _inputSplines . Count ( ) > 1 ;
165162 if ( ! createMergeNode )
166163 return true ;
167164
168- // Create merge node to merge branching splines
169165 HAPI_NodeId mergeNodeId = HEU_Defines . HEU_INVALID_NODE_ID ;
170166 HAPI_NodeId parentId = HEU_HAPIUtility . GetParentNodeID ( session , inputNodeID ) ;
171167
172- if ( ! session . CreateNode ( parentId , "merge" , "rajat-merge" , false , out mergeNodeId ) )
168+ if ( ! session . CreateNode ( parentId , "merge" , null , false , out mergeNodeId ) )
173169 {
174170 HEU_Logger . LogErrorFormat ( "Unable to create merge SOP node for connecting input assets." ) ;
175171 return false ;
@@ -187,21 +183,20 @@ public override bool CreateInputNodeWithDataUpload(HEU_SessionBase session, HAPI
187183 }
188184 inputNodeID = mergeNodeId ;
189185
186+ Matrix4x4 localToWorld = inputSplines . _transform . localToWorldMatrix ;
190187 HAPI_NodeId branchNodeID ;
191- string branchName = inputObject . name ;
192188 HEU_InputDataSpline branchSpline ;
193- int inputNodeIndex = 1 ;
194189 for ( int i = 1 ; i < inputSplines . _inputSplines . Count ( ) ; i ++ )
195190 {
196- session . CreateInputCurveNode ( out branchNodeID , branchName + "_" + i ) ;
191+ session . CreateInputCurveNode ( out branchNodeID , inputObject . name + "_" + i ) ;
197192 if ( branchNodeID == HEU_Defines . HEU_INVALID_NODE_ID || ! HEU_HAPIUtility . IsNodeValidInHoudini ( session , branchNodeID ) )
198193 {
199194 HEU_Logger . LogError ( "Failed to create new input cruve node in Houdini session!" ) ;
200195 return false ;
201196 }
202197
203198 branchSpline = inputSplines . _inputSplines [ i ] ;
204- if ( ! UploadData ( session , branchNodeID , branchSpline , true ) )
199+ if ( ! UploadData ( session , branchNodeID , branchSpline , localToWorld ) )
205200 {
206201 if ( ! session . CookNode ( branchNodeID , false ) )
207202 {
@@ -216,7 +211,6 @@ public override bool CreateInputNodeWithDataUpload(HEU_SessionBase session, HAPI
216211 HEU_Logger . LogErrorFormat ( "Unable to connect to input node!" ) ;
217212 return false ;
218213 }
219- inputNodeIndex ++ ;
220214 }
221215
222216 if ( ! session . CookNode ( inputNodeID , false ) )
@@ -234,7 +228,6 @@ public override bool CreateInputNodeWithDataUpload(HEU_SessionBase session, HAPI
234228 public class HEU_InputDataSpline
235229 {
236230 public Spline _spline ;
237- public Transform _transform ;
238231 public bool _closed ;
239232 public int _count ;
240233 public float _length ;
@@ -244,9 +237,10 @@ public class HEU_InputDataSpline
244237 /// <summary>
245238 /// Contains input geometry for multiple splines.
246239 /// </summary>
247- public class HEU_InputDataSplines : HEU_InputData
240+ public class HEU_InputDataSplineContainer : HEU_InputData
248241 {
249242 public List < HEU_InputDataSpline > _inputSplines = new List < HEU_InputDataSpline > ( ) ;
243+ public Transform _transform ;
250244 }
251245
252246 /// <summary>
@@ -255,25 +249,26 @@ public class HEU_InputDataSplines : HEU_InputData
255249 /// </summary>
256250 /// <param name="inputObject">GameObject containing a Spline component</param>
257251 /// <returns>A valid input data strcuture containing spline data</returns>
258- public HEU_InputDataSplines GenerateSplineDataFromGameObject ( GameObject inputObject )
252+ public HEU_InputDataSplineContainer GenerateSplineDataFromGameObject ( GameObject inputObject )
259253 {
260254 SplineContainer splineContainer = inputObject . GetComponent < SplineContainer > ( ) ;
261255 IReadOnlyList < Spline > splines = splineContainer . Splines ;
262256
263- HEU_InputDataSplines splineData = new HEU_InputDataSplines ( ) ;
257+ HEU_InputDataSplineContainer splineContainerData = new HEU_InputDataSplineContainer ( ) ;
264258 foreach ( Spline spline in splines )
265259 {
266- HEU_InputDataSpline inputSpline = new HEU_InputDataSpline ( ) ;
267- inputSpline . _spline = spline ;
268- inputSpline . _transform = inputObject . transform ;
269- inputSpline . _closed = spline . Closed ;
270- inputSpline . _count = spline . Count ;
271- inputSpline . _length = spline . GetLength ( ) ;
272- inputSpline . _knots = spline . Knots . ToArray < BezierKnot > ( ) ;
273-
274- splineData . _inputSplines . Add ( inputSpline ) ;
260+ HEU_InputDataSpline splineData = new HEU_InputDataSpline ( ) ;
261+ splineData . _spline = spline ;
262+ splineData . _closed = spline . Closed ;
263+ splineData . _count = spline . Count ;
264+ splineData . _length = spline . GetLength ( ) ;
265+ splineData . _knots = spline . Knots . ToArray < BezierKnot > ( ) ;
266+
267+ splineContainerData . _inputSplines . Add ( splineData ) ;
275268 }
276- return splineData ;
269+ splineContainerData . _transform = inputObject . transform ;
270+
271+ return splineContainerData ;
277272 }
278273
279274 /// <summary>
@@ -283,16 +278,14 @@ public HEU_InputDataSplines GenerateSplineDataFromGameObject(GameObject inputObj
283278 /// <param name="inputNodeID">ID of the input node</param>
284279 /// <param name="inputData">Container of the mesh geometry</param>
285280 /// <returns>True if successfully uploaded data</returns>
286- public bool UploadData ( HEU_SessionBase session , HAPI_NodeId inputNodeID , HEU_InputDataSpline inputSpline , bool toWorld = false )
281+ public bool UploadData ( HEU_SessionBase session , HAPI_NodeId inputNodeID , HEU_InputDataSpline inputSpline , Matrix4x4 localToWorld )
287282 {
288283 // Set the input curve info of the newly created input curve
289284 HAPI_InputCurveInfo inputCurveInfo = new HAPI_InputCurveInfo ( ) ;
290285 inputCurveInfo . curveType = HAPI_CurveType . HAPI_CURVETYPE_BEZIER ;
291- inputCurveInfo . order = 4 ; // Recommended default
286+ inputCurveInfo . order = 4 ;
292287 inputCurveInfo . closed = inputSpline . _closed ;
293288 inputCurveInfo . reverse = false ;
294-
295- // Curve always goes through the specified points
296289 inputCurveInfo . inputMethod = HAPI_InputCurveMethod . HAPI_CURVEMETHOD_BREAKPOINTS ;
297290 inputCurveInfo . breakpointParameterization = HAPI_InputCurveParameterization . HAPI_CURVEPARAMETERIZATION_UNIFORM ;
298291 if ( ! session . SetInputCurveInfo ( inputNodeID , 0 , ref inputCurveInfo ) )
@@ -301,18 +294,16 @@ public bool UploadData(HEU_SessionBase session, HAPI_NodeId inputNodeID, HEU_Inp
301294 return false ;
302295 }
303296
304- // Calculate the number of refined point we want
297+ // Calculate the number of refined points we want
305298 int numControlPoints = inputSpline . _knots . Count ( ) ;
306299 float splineLength = inputSpline . _length ;
307- float splineResolution = settings != null ? settings . SamplingResolution : 0.5f ;
308-
300+ float splineResolution = settings != null ? settings . SamplingResolution : 0.0f ;
309301 int numRefinedSplinePoints = splineResolution > 0.0f ? Mathf . CeilToInt ( splineLength / splineResolution ) + 1 : numControlPoints ;
310- Matrix4x4 localToWorld = inputSpline . _transform . localToWorldMatrix ;
311302
312303 float [ ] posArr ;
313304 float [ ] rotArr ;
314305 float [ ] scaleArr ;
315- if ( numRefinedSplinePoints < numControlPoints )
306+ if ( numRefinedSplinePoints <= numControlPoints )
316307 {
317308 // There's not enough refined points, so we'll use the control points instead
318309 posArr = new float [ numControlPoints * 3 ] ;
@@ -321,7 +312,10 @@ public bool UploadData(HEU_SessionBase session, HAPI_NodeId inputNodeID, HEU_Inp
321312 for ( int i = 0 ; i < numControlPoints ; i ++ )
322313 {
323314 BezierKnot knot = inputSpline . _knots [ i ] ;
324- float3 pos = toWorld ? localToWorld . MultiplyPoint ( knot . Position ) : knot . Position ;
315+
316+ // For branching sub-splines, apply local transform on vertices to get the merged spline
317+ float3 pos = localToWorld . MultiplyPoint ( knot . Position ) ;
318+
325319 HEU_HAPIUtility . ConvertPositionUnityToHoudini ( pos , out posArr [ i * 3 + 0 ] , out posArr [ i * 3 + 1 ] , out posArr [ i * 3 + 2 ] ) ;
326320 HEU_HAPIUtility . ConvertRotationUnityToHoudini ( knot . Rotation , out rotArr [ i * 4 + 0 ] , out rotArr [ i * 4 + 1 ] , out rotArr [ i * 4 + 2 ] , out rotArr [ i * 4 + 3 ] ) ;
327321 }
@@ -336,22 +330,32 @@ public bool UploadData(HEU_SessionBase session, HAPI_NodeId inputNodeID, HEU_Inp
336330 for ( int i = 0 ; i < numRefinedSplinePoints ; i ++ )
337331 {
338332 float3 pos = SplineUtility . EvaluatePosition < Spline > ( inputSpline . _spline , currentDistance / splineLength ) ;
339- if ( toWorld )
340- {
341- pos = localToWorld . MultiplyPoint ( pos ) ;
342- }
343- HEU_HAPIUtility . ConvertPositionUnityToHoudini ( pos , out posArr [ i * 3 + 0 ] , out posArr [ i * 3 + 1 ] , out posArr [ i * 3 + 2 ] ) ;
333+
334+ // For branching sub-splines, apply local transform on vertices to get the merged spline
335+ pos = localToWorld . MultiplyPoint ( pos ) ;
344336
337+ HEU_HAPIUtility . ConvertPositionUnityToHoudini ( pos , out posArr [ i * 3 + 0 ] , out posArr [ i * 3 + 1 ] , out posArr [ i * 3 + 2 ] ) ;
345338 currentDistance += splineResolution ;
346339 }
347340 }
348341
349- bool hapi_result = session . SetInputCurvePositionsRotationsScales (
350- inputNodeID , 0 ,
351- posArr , 0 , posArr . Length ,
352- rotArr , 0 , rotArr . Length ,
353- scaleArr , 0 , 0
354- ) ;
342+ bool hasRotations = rotArr . Length == posArr . Length ;
343+ bool hasScales = scaleArr . Length == posArr . Length ;
344+ bool hapi_result = false ;
345+ if ( ! hasRotations && ! hasScales )
346+ {
347+ hapi_result = session . SetInputCurvePositions ( inputNodeID , 0 , posArr , 0 , posArr . Length ) ;
348+ }
349+ else
350+ {
351+ hapi_result = session . SetInputCurvePositionsRotationsScales (
352+ inputNodeID , 0 ,
353+ posArr , 0 , posArr . Length ,
354+ rotArr , 0 , rotArr . Length ,
355+ scaleArr , 0 , 0
356+ ) ;
357+ }
358+
355359 if ( ! hapi_result )
356360 {
357361 HEU_Logger . LogError ( "Failed to set input curve positions." ) ;
0 commit comments