<div dir="ltr"><div dir="ltr"><div dir="ltr">I've decided to go two ways. I will provide both motions and interpolators.  Then we can add a flag to switch between them.  I am not certain of the order of loc or axa at this point, I want to look at the data further.<div><br></div><div>Here's the barely tested interpolator code (only Armatures right now, sorry).</div><div><br></div><div><div>                  print(f"Exporting interpolators of {tag} {obj.type}")</div><div>                  children = []</div><div>                  if obj.type == 'ARMATURE':</div><div>                      armature = obj</div><div>                      bpy.context.view_layer.objects.active = armature</div><div>                      bpy.ops.object.mode_set(mode='POSE')</div><div>                      print(f"Activated armature {armature} in pose mode")</div><div>                      if armature:</div><div>                            animation_data = armature.animation_data</div><div>                            if animation_data:</div><div>                                print(f"Exporting animation data")</div><div>                                action = animation_data.action</div><div>                                if action:</div><div>                                    numbones = len(armature.pose.bones)</div><div>                                    frame_range = action.frame_range</div><div>                                    keyframe_length = (frame_range[1] - frame_range[0]) / bpy.context.scene.render.fps</div><div><br></div><div>                                    keyframe_time = 0</div><div><br></div><div>                                    time_sensor = TimeSensor(cycleInterval=(frame_range[1] - frame_range[0]), loop=True, enabled=True)</div><div>                                    clock_name = name+"_Clock"</div><div>                                    setUSEDEF(clock_name, None, time_sensor)</div><div>                                    activate_sensor = ProximitySensor(size=[ 1000000, 1000000, 1000000 ])</div><div>                                    activate_name = name+"_Close"</div><div>                                    setUSEDEF(activate_name, None, activate_sensor)</div><div>                                    activate_route = ROUTE(</div><div>                                            fromNode=activate_name,</div><div>                                            fromField="enterTime",</div><div>                                            toNode=clock_name,</div><div>                                            toField="startTime")</div><div><br></div><div>                                    positionInterpolators = []</div><div>                                    orientationInterpolators = []</div><div>                                    positionRoutes = []</div><div>                                    orientationRoutes = []</div><div>                                    for b in range(numbones):</div><div>                                        bone = armature.pose.bones[b]</div><div>                                        posInterp = PositionInterpolator()</div><div>                                        setUSEDEF(name+"_PI_", <a href="http://bone.name">bone.name</a>, posInterp)</div><div>                                        positionInterpolators.append(posInterp)</div><div>                                        positionRoutes.append(ROUTE(</div><div>                                            fromNode=clock_name,</div><div>                                            fromField="fraction_changed",</div><div>                                            toNode=name+"_PI_"+<a href="http://bone.name">bone.name</a>,</div><div>                                            toField="set_fraction"))</div><div>                                        positionRoutes.append(ROUTE(</div></div><div><div>                                            fromNode=name+"_PI_"+<a href="http://bone.name">bone.name</a>,</div><div>                                            fromField="value_changed",</div><div>                                            toNode=HANIM_DEF_PREFIX+<a href="http://bone.name">bone.name</a>,</div><div>                                            toField="translation"))</div><div><br></div><div>                                        rotInterp = OrientationInterpolator()</div><div>                                        setUSEDEF(name+"_OI_", <a href="http://bone.name">bone.name</a>, rotInterp)</div><div>                                        orientationInterpolators.append(rotInterp)</div><div>                                        orientationRoutes.append(ROUTE(</div><div>                                            fromNode=clock_name,</div><div>                                            fromField="fraction_changed",</div><div>                                            toNode=name+"_OI_"+<a href="http://bone.name">bone.name</a>,</div><div>                                            toField="set_fraction"))</div><div>                                        orientationRoutes.append(ROUTE(</div><div>                                            fromNode=name+"_OI_"+<a href="http://bone.name">bone.name</a>,</div><div>                                            fromField="value_changed",</div><div>                                            toNode=HANIM_DEF_PREFIX+<a href="http://bone.name">bone.name</a>,</div><div>                                            toField="rotation"))</div><div>                                    for frame in range(int(action.frame_range.x), int(action.frame_range.y) + 1):</div><div>                                        # frame is frame number</div><div>                                        bpy.context.scene.frame_set(frame)</div><div>                                        print(f"Exporting frame {frame}")</div><div>                                        for b in range(numbones):</div><div>                                            bone = armature.pose.bones[b]</div><div>                                            bone.rotation_mode = 'AXIS_ANGLE'</div><div>                                            positionInterpolators[b].key.append(keyframe_time)</div><div>                                            loc = [</div><div>                                                bone.location[0]*lengthUnitConversion, # location</div><div>                                                bone.location[2]*lengthUnitConversion, # location  reverse Y and Z for X3D</div><div>                                                bone.location[1]*lengthUnitConversion # location  reverse Y and Z for X3D</div><div>                                                ]</div><div>                                            positionInterpolators[b].keyValue.append(loc) # location</div><div>                                            axa = bone.rotation_axis_angle</div><div>                                            rot = [axa[0], axa[1], axa[2], axa[3]]</div><div>                                            orientationInterpolators[b].key.append(keyframe_time)</div><div>                                            orientationInterpolators[b].keyValue.append(rot) # SFRotation</div><div>                                        keyframe_time = keyframe_time + keyframe_length</div><div>                                    children.append(time_sensor)</div><div>                                    children.append(activate_sensor)</div><div>                                    children.append(activate_route)</div><div>                                    children.append(positionInterpolators[:])</div><div>                                    children.append(positionRoutes[:])</div><div>                                    children.append(orientationInterpolators[:])</div><div>                                    children.append(orientationRoutes[:])</div></div><div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Oct 14, 2023 at 6:54 AM GPU Group <<a href="mailto:gpugroup@gmail.com">gpugroup@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">The Blender > Export/Import > mocap bvh code may have some hints. <div>Hypothesis: on import it converts from mocap to interpolators, on export goes the other way.</div><div><br></div><div>Q. do you think that HAnim 5.2.4 Angle Conversion Procedure is sufficient to imply Motion data is in degrees? It doesn't mention the Motion node explicitly (Hypothesis written in an early era).. If so we could make the Motion.values degrees by default, as Joe suggested and 5.2.4 'indirectly implies'? </div><div>-Doug</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Oct 14, 2023 at 2:47 AM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Here's the Euler Angle to Axis-Angle in HAnim Pt section 5.2.4<div><br></div><div><a href="https://www.web3d.org/documents/specifications/19774/V2.0/MotionDataAnimation/AnimationUsingInterpolators.html#AngleConversionProcedure" target="_blank">https://www.web3d.org/documents/specifications/19774/V2.0/MotionDataAnimation/AnimationUsingInterpolators.html#AngleConversionProcedure</a><br></div><div><br></div><div>Hmm!  I'm guessing that Blender has a routine for this! Sure enough!  Trying it now.</div><div><br></div><div>Not with HAnimMotion, I don't know how to do that yet.  Suggestions?</div><div><br></div><div>John</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Oct 14, 2023 at 12:21 AM Joe D Williams <<a href="mailto:joedwil@earthlink.net" target="_blank">joedwil@earthlink.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:12pt"><p style="margin:0.1rem 0px;line-height:1">> <span style="font-size:12pt">Um, then why is angle even listed here?</span></p>
<p style="margin:0.1rem 0px;line-height:1">  </p>
<p style="margin:0.1rem 0px;line-height:1">That is easy, take another look. </p>
<p style="margin:0.1rem 0px;line-height:1">Euler angles are not listed anywhere! </p>
<p style="margin:0.1rem 0px;line-height:1">Convert to axis-angle like showed in Part 2 and forget xyz angles/</p>
<p style="margin:0.1rem 0px;line-height:1">Joe</p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
</div>
<div style="border-left:1px solid rgb(170,170,170);box-sizing:border-box;padding:10px 0px 10px 15px;margin:0px">
<p>-----Original Message-----<br>From: John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>><br>Sent: Oct 13, 2023 6:15 PM<br>To: Joe D Williams <<a href="mailto:joedwil@earthlink.net" target="_blank">joedwil@earthlink.net</a>><br>Cc: <<a href="mailto:x3d-public@web3d.org" target="_blank">x3d-public@web3d.org</a>><br>Subject: Re: [x3d-public] Units for BVH vs HAnimMotion.values</p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Um, then why is angle even listed here?
<div> </div>
<div>Confusing as heck!</div>
<div> </div>
<div><a href="https://www.web3d.org/documents/specifications/19775-1/V4.0/Part01/concepts.html#t-Standardunits" target="_blank">https://www.web3d.org/documents/specifications/19775-1/V4.0/Part01/concepts.html#t-Standardunits</a></div>
<div> </div>
<div>John</div>
<div> </div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div class="gmail_attr" dir="ltr">On Fri, Oct 13, 2023 at 7:19 PM Joe D Williams <<a href="mailto:joedwil@earthlink.net" target="_blank">joedwil@earthlink.net</a>> wrote:</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:12pt">
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">> otherwise specified in a UNIT statement </span></p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline"><a href="https://www.web3d.org/documents/specifications/19775-1/V4.0/Part01/concepts.html#Standardunitscoordinates" rel="noopener" target="_blank">https://www.web3d.org/documents/specifications/19775-1/V4.0/Part01/concepts.html#Standardunitscoordinates</a></span></p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">"However, the world coordinate units may be modified by specifying a different length unit using the UNIT statement."</span></p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">There is Not Now nor will there Ever be a UNIT statement that allows degrees for rotation and orientation. </span></p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">Never, will angles appear in any x3d animation interpolator. </span></p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">To apply an import using angle units, it is converted to x3d before use, then discarded or possibly stored somewhere away from working area for reference.  </span></p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">Thanks and Best,</span></p>
<p style="margin:0.1rem 0px;line-height:1"><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium;white-space:normal;float:none;display:inline">Joe</span></p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
</div>
<div style="border-left:1px solid rgb(170,170,170);box-sizing:border-box;padding:10px 0px 10px 15px;margin:0px">
<p>-----Original Message-----<br>From: John Carlson <<a href="mailto:yottzumm@gmail.com" rel="noopener" target="_blank">yottzumm@gmail.com</a>><br>Sent: Oct 13, 2023 11:44 AM<br>To: X3D Graphics public mailing list <<a href="mailto:x3d-public@web3d.org" rel="noopener" target="_blank">x3d-public@web3d.org</a>><br>Subject: [x3d-public] Units for BVH vs HAnimMotion.values</p>
<p style="margin:0.1rem 0px;line-height:1"> </p>
Apparently BVH uses degrees for rotations.  Units for HAnimMotion should use radians unless otherwise specified in a UNIT statement, AFAIK.
<div dir="auto"> </div>
<div dir="auto">Comments?</div>
<div dir="auto"> </div>
<div dir="auto">Thanks!</div>
<div dir="auto"> </div>
<div dir="auto">John </div>
</div>
<p style="margin:0.1rem 0px;line-height:1"> </p>
</blockquote>
</div>
</div>

<p style="margin:0.1rem 0px;line-height:1"> </p></blockquote></div>
_______________________________________________<br>
x3d-public mailing list<br>
<a href="mailto:x3d-public@web3d.org" target="_blank">x3d-public@web3d.org</a><br>
<a href="http://web3d.org/mailman/listinfo/x3d-public_web3d.org" rel="noreferrer" target="_blank">http://web3d.org/mailman/listinfo/x3d-public_web3d.org</a><br>
</blockquote></div>
</blockquote></div>