From 3ca770cd2c7705d53efe11bb2a2315392b1f492a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 10 Aug 2012 08:33:09 -0700 Subject: BulletSim: Add module names to DetailLog output. Fix some problems with linksets that were caused by checking data structures that are changed regularly from taint time code -- resulted in linksets not being unlinked properly. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 8 ++- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 57 +++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 69 ++++++++++++---------- 3 files changed, 71 insertions(+), 63 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d49a578..4f48cfb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -248,7 +248,7 @@ public class BSCharacter : PhysicsActor // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); Scene.TaintedObject("BSCharacter.SetForce", delegate() { - DetailLog("{0},setForce,taint,force={1}", LocalID, _force); + DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force); }); } @@ -275,7 +275,7 @@ public class BSCharacter : PhysicsActor // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); _scene.TaintedObject("BSCharacter.setVelocity", delegate() { - DetailLog("{0},setVelocity,taint,vel={1}", LocalID, _velocity); + DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); }); } @@ -487,6 +487,10 @@ public class BSCharacter : PhysicsActor _rotationalVelocity = entprop.RotationalVelocity; // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); + + DetailLog("{0},BSCharacter.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, + entprop.Acceleration, entprop.RotationalVelocity); } // Called by the scene when a collision with this object is reported diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index bf262c5..f68e06e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -40,9 +40,12 @@ public class BSLinkset public BSPrim Root { get { return m_linksetRoot; } } private BSScene m_scene; + public BSScene Scene { get { return m_scene; } } private List m_children; + public int NumberOfChildren { get { return m_children.Count; } } + // We lock the diddling of linkset classes to prevent any badness. // This locks the modification of the instances of this class. Changes // to the physical representation is done via the tainting mechenism. @@ -113,9 +116,10 @@ public class BSLinkset } // The child is down to a linkset of just itself - return new BSLinkset(m_scene, child); + return new BSLinkset(Scene, child); } + /* DEPRECATED: this is really bad in that it trys to unlink other prims. // An existing linkset had one of its members rebuilt or something. // Go through the linkset and rebuild the pointers to the bodies of the linkset members. public BSLinkset RefreshLinkset(BSPrim requestor) @@ -163,6 +167,7 @@ public class BSLinkset return ret; } + */ // Return 'true' if the passed object is the root object of this linkset @@ -229,18 +234,19 @@ public class BSLinkset } // I am the root of a linkset and a new child is being added - public void AddChildToLinkset(BSPrim pchild) + // Called while LinkActivity is locked. + public void AddChildToLinkset(BSPrim child) { - BSPrim child = pchild; if (!HasChild(child)) { m_children.Add(child); + BSPrim root = Root; // capture the root as of now m_scene.TaintedObject("AddChildToLinkset", delegate() { DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); - DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); - PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child + DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); + PhysicallyLinkAChildToRoot(root, child); // build the physical binding between me and the child }); } return; @@ -259,26 +265,17 @@ public class BSLinkset // I am the root of a linkset and one of my children is being removed. // Safe to call even if the child is not really in my linkset. - public void RemoveChildFromLinkset(BSPrim pchild) + public void RemoveChildFromLinkset(BSPrim child) { - BSPrim child = pchild; - if (m_children.Remove(child)) { + BSPrim root = Root; // capture the root as of now m_scene.TaintedObject("RemoveChildFromLinkset", delegate() { DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); - DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); + DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); - if (m_children.Count == 0) - { - // if the linkset is empty, make sure all linkages have been removed - PhysicallyUnlinkAllChildrenFromRoot(); - } - else - { - PhysicallyUnlinkAChildFromRoot(pchild); - } + PhysicallyUnlinkAChildFromRoot(root, child); }); } else @@ -291,14 +288,14 @@ public class BSLinkset // Create a constraint between me (root of linkset) and the passed prim (the child). // Called at taint time! - private void PhysicallyLinkAChildToRoot(BSPrim childPrim) + private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(); // relative position normalized to the root prim - OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation); - OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation; + OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); + OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; // relative rotation of the child to the parent OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; @@ -306,9 +303,9 @@ public class BSLinkset // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); - DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); + DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( - m_scene.World, m_linksetRoot.Body, childPrim.Body, + m_scene.World, rootPrim.Body, childPrim.Body, childRelativePosition, childRelativeRotation, OMV.Vector3.Zero, @@ -331,25 +328,25 @@ public class BSLinkset // Remove linkage between myself and a particular child // Called at taint time! - private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim) + private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) { // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", - // LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); - DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); + // LogHeader, rootPrim.LocalID, childPrim.LocalID); + DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); - m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body); + m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); // Make the child refresh its location BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); } // Remove linkage between myself and any possible children I might have // Called at taint time! - private void PhysicallyUnlinkAllChildrenFromRoot() + private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) { // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); - DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID); + DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); - m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body); + m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); } // Invoke the detailed logger and output something if it's enabled. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 988e03b..4193d22 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -160,16 +160,18 @@ public sealed class BSPrim : PhysicsActor public void Destroy() { // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); - // DetailLog("{0},Destroy", LocalID); + // DetailLog("{0},BSPrim.Destroy", LocalID); // Undo any vehicle properties _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); _scene.RemoveVehiclePrim(this); // just to make sure + // Undo any links between me and any other object + _linkset = _linkset.RemoveMeFromLinkset(this); + _scene.TaintedObject("BSPrim.destroy", delegate() { - // Undo any links between me and any other object - _linkset = _linkset.RemoveMeFromLinkset(this); + DetailLog("{0},BSPrim.Destroy,taint,", LocalID); // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); @@ -187,7 +189,7 @@ public sealed class BSPrim : PhysicsActor { _mass = CalculateMass(); // changing size changes the mass BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); - // DetailLog("{0}: setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); + // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); RecreateGeomAndObject(); }); } @@ -227,7 +229,7 @@ public sealed class BSPrim : PhysicsActor if (parent != null) { DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); - DetailLog("{0},link,parent={1}", LocalID, parent.LocalID); + DetailLog("{0},BSPrim.link,parent={1}", LocalID, parent.LocalID); _linkset = _linkset.AddMeToLinkset(this, parent); } return; @@ -239,9 +241,14 @@ public sealed class BSPrim : PhysicsActor // Race condition here: if link() and delink() in same simulation tick, the delink will not happen DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString()); - DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString()); - _linkset.RemoveMeFromLinkset(this); + BSPrim parentBefore = _linkset.Root; + int childrenBefore = _linkset.NumberOfChildren; + + _linkset = _linkset.RemoveMeFromLinkset(this); + + DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", + LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); return; } @@ -264,7 +271,7 @@ public sealed class BSPrim : PhysicsActor public override void LockAngularMotion(OMV.Vector3 axis) { - DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis); + DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); return; } @@ -283,7 +290,7 @@ public sealed class BSPrim : PhysicsActor // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? _scene.TaintedObject("BSPrim.setPosition", delegate() { - DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); }); } @@ -320,7 +327,7 @@ public sealed class BSPrim : PhysicsActor _force = value; _scene.TaintedObject("BSPrim.setForce", delegate() { - DetailLog("{0},setForce,taint,force={1}", LocalID, _force); + DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); BulletSimAPI.SetObjectForce2(Body.Ptr, _force); }); @@ -335,7 +342,7 @@ public sealed class BSPrim : PhysicsActor Vehicle type = (Vehicle)value; _scene.TaintedObject("BSPrim.setVehicleType", delegate() { - DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type); + DetailLog("{0},BSPrim.SetVehicleType,taint,type={1}", LocalID, type); _vehicle.ProcessTypeChange(type); if (type == Vehicle.TYPE_NONE) { @@ -405,7 +412,7 @@ public sealed class BSPrim : PhysicsActor _velocity = value; _scene.TaintedObject("BSPrim.setVelocity", delegate() { - DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity); + DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); }); } @@ -413,7 +420,7 @@ public sealed class BSPrim : PhysicsActor public override OMV.Vector3 Torque { get { return _torque; } set { _torque = value; - DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque); + DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); } } public override float CollisionScore { @@ -440,7 +447,7 @@ public sealed class BSPrim : PhysicsActor _scene.TaintedObject("BSPrim.setOrientation", delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); - DetailLog("{0},setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); }); } @@ -486,7 +493,7 @@ public sealed class BSPrim : PhysicsActor // Bullet wants static objects to have a mass of zero float mass = IsStatic ? 0f : _mass; - DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); + DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); } @@ -544,7 +551,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { - DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); + DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); }); } @@ -561,7 +568,7 @@ public sealed class BSPrim : PhysicsActor _buoyancy = value; _scene.TaintedObject("BSPrim.setBuoyancy", delegate() { - DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); + DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); }); } @@ -624,17 +631,17 @@ public sealed class BSPrim : PhysicsActor } m_accumulatedForces.Clear(); } - DetailLog("{0},AddObjectForce,taint,force={1}", LocalID, _force); + DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); }); } public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { - DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); + DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); } public override void SetMomentum(OMV.Vector3 momentum) { - DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum); + DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); } public override void SubscribeEvents(int ms) { _subscribedEventsMs = ms; @@ -978,7 +985,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) { - DetailLog("{0},CreateGeom,sphere (force={1}", LocalID, forceRebuild); + DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; // Bullet native objects are scaled by the Bullet engine so pass the size in _scale = _size; @@ -992,7 +999,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) { - DetailLog("{0},CreateGeom,box (force={1})", LocalID, forceRebuild); + DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _scale = _size; // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? @@ -1035,12 +1042,12 @@ public sealed class BSPrim : PhysicsActor // if this new shape is the same as last time, don't recreate the mesh if (_meshKey == newMeshKey) return; - DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, newMeshKey); + DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); // Since we're recreating new, get rid of any previously generated shape if (_meshKey != 0) { // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); - DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); + DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; _meshKey = 0; @@ -1070,7 +1077,7 @@ public sealed class BSPrim : PhysicsActor _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); - DetailLog("{0},CreateGeomMesh,done", LocalID); + DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); return; } @@ -1084,17 +1091,17 @@ public sealed class BSPrim : PhysicsActor // if the hull hasn't changed, don't rebuild it if (newHullKey == _hullKey) return; - DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey); + DetailLog("{0},BSPrim.CreateGeomHull,create,key={1}", LocalID, _meshKey); // Since we're recreating new, get rid of any previously generated shape if (_hullKey != 0) { // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); - DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey); + DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); _hullKey = 0; _hulls.Clear(); - DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); + DetailLog("{0},BSPrim.CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; // the mesh cannot match either _meshKey = 0; @@ -1191,7 +1198,7 @@ public sealed class BSPrim : PhysicsActor _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); - DetailLog("{0},CreateGeomHull,done", LocalID); + DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); return; } @@ -1329,7 +1336,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); - DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); base.RequestPhysicsterseUpdate(); @@ -1337,7 +1344,7 @@ public sealed class BSPrim : PhysicsActor else { // For debugging, we also report the movement of children - DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + DetailLog("{0},BSPrim.BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } -- cgit v1.1