示例#1
0
        // Adds a new object to the scene - attaches a body to the geom and
        // sets the initial position and orientation
        static void addObject(IntPtr geom, d.Mass mass)
        {
            // Create a body for this object
            IntPtr body = d.BodyCreate(world);

            d.GeomSetBody(geom, body);
            d.BodySetMass(body, ref mass);
            obj.Enqueue(geom);

            // Set the position of the new object
            d.Matrix3 R;
            d.BodySetPosition(body, d.RandReal() * 2 - 1, d.RandReal() * 2 - 1, d.RandReal() + 2);
            d.RFromAxisAndAngle(out R, d.RandReal() * 2 - 1, d.RandReal() * 2 - 1, d.RandReal() * 2 - 1, d.RandReal() * 10 - 5);
            d.BodySetRotation(body, ref R);

            // Cap the total number of objects
            if (obj.Count > NUM)
            {
                geom = obj.Dequeue();
                body = d.GeomGetBody(geom);
                d.BodyDestroy(body);
                d.GeomDestroy(geom);
            }
        }
示例#2
0
        public void MakeBody ()
        {
            //            d.Vector3 dvtmp;
            //            d.Vector3 dbtmp;

            d.Mass tmpdmass = new d.Mass
            {
            };
            d.Mass objdmass = new d.Mass
            {
            };

            d.Matrix3 mat = new d.Matrix3 ();
            d.Matrix3 mymat = new d.Matrix3 ();
            d.Quaternion quat = new d.Quaternion ();
            d.Quaternion myrot = new d.Quaternion ();
            Vector3 rcm;

            if (childPrim)  // child prims don't get own bodies;
                return;

            if (Body != IntPtr.Zero) // who shouldn't have one already ?
            {
                d.BodyDestroy (Body);
                Body = IntPtr.Zero;
            }

            if (!m_isphysical) // only physical things get a body
                return;
            Body = d.BodyCreate (_parent_scene.world);

            calcdMass (); // compute inertia on local frame

            DMassDup (ref primdMass, out objdmass);

            // rotate inertia
            myrot.X = _orientation.X;
            myrot.Y = _orientation.Y;
            myrot.Z = _orientation.Z;
            myrot.W = _orientation.W;

            d.RfromQ (out mymat, ref myrot);
            d.MassRotate (ref objdmass, ref mymat);

            // set the body rotation and position
            d.BodySetRotation (Body, ref mymat);

            // recompute full object inertia if needed
            if (childrenPrim.Count > 0)
            {

                rcm.X = _position.X + objdmass.c.X;
                rcm.Y = _position.Y + objdmass.c.Y;
                rcm.Z = _position.Z + objdmass.c.Z;

                lock (childrenPrim)
                {
                    foreach (AuroraODEPrim prm in childrenPrim)
                    {
                        prm.calcdMass (); // recompute inertia on local frame
                        DMassCopy (ref prm.primdMass, ref tmpdmass);

                        // apply prim current rotation to inertia
                        quat.W = prm._orientation.W;
                        quat.X = prm._orientation.X;
                        quat.Y = prm._orientation.Y;
                        quat.Z = prm._orientation.Z;
                        d.RfromQ (out mat, ref quat);
                        d.MassRotate (ref tmpdmass, ref mat);

                        Vector3 ppos = prm._position;
                        ppos.X += tmpdmass.c.X - rcm.X;
                        ppos.Y += tmpdmass.c.Y - rcm.Y;
                        ppos.Z += tmpdmass.c.Z - rcm.Z;

                        // refer inertia to root prim center of mass position
                        d.MassTranslate (ref tmpdmass,
                            ppos.X,
                            ppos.Y,
                            ppos.Z);

                        d.MassAdd (ref objdmass, ref tmpdmass); // add to total object inertia

                        // fix prim colision cats
                        if (prm.prim_geom == IntPtr.Zero)
                        {
                            m_log.Warn ("[PHYSICS]: Unable to link one of the linkset elements.  No geom yet");
                            continue;
                        }

                        d.GeomClearOffset (prm.prim_geom);
                        d.GeomSetBody (prm.prim_geom, Body);
                        d.GeomSetOffsetWorldRotation (prm.prim_geom, ref mat); // set relative rotation
                    }
                }
            }

            d.GeomClearOffset (prim_geom); // make sure we don't have a hidden offset
            // associate root geom with body
            d.GeomSetBody (prim_geom, Body);

            d.BodySetPosition (Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z);
            d.GeomSetOffsetWorldPosition (prim_geom, _position.X, _position.Y, _position.Z);

            d.MassTranslate (ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
            myrot.W = -myrot.W;
            d.RfromQ (out mymat, ref myrot);
            d.MassRotate (ref objdmass, ref mymat);
            d.BodySetMass (Body, ref objdmass);
            _mass = objdmass.mass;

            m_collisionCategories |= CollisionCategories.Body;
            m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);

            // disconnect from world gravity so we can apply buoyancy
            if (!testRealGravity)
                d.BodySetGravityMode (Body, false);

            d.BodySetAutoDisableFlag (Body, true);
            d.BodySetAutoDisableSteps (Body, body_autodisable_frames);
            //            d.BodySetLinearDampingThreshold(Body, 0.01f);
            //            d.BodySetAngularDampingThreshold(Body, 0.001f);
            d.BodySetDamping (Body, .001f, .001f);
            m_disabled = false;

            d.GeomSetCategoryBits (prim_geom, (int)m_collisionCategories);
            d.GeomSetCollideBits (prim_geom, (int)m_collisionFlags);

            m_interpenetrationcount = 0;
            m_collisionscore = 0;

            if (m_targetSpace != _parent_scene.space)
            {
                _parent_scene.waitForSpaceUnlock (m_targetSpace);
                if (d.SpaceQuery (m_targetSpace, prim_geom))
                    d.SpaceRemove (m_targetSpace, prim_geom);

                m_targetSpace = _parent_scene.space;
                d.SpaceAdd (m_targetSpace, prim_geom);
            }

            lock (childrenPrim)
            {
                foreach (AuroraODEPrim prm in childrenPrim)
                {
                    if (prm.prim_geom == IntPtr.Zero)
                    {
                        m_log.Warn ("[PHYSICS]: Unable to link one of the linkset elements.  No geom yet");
                        continue;
                    }
                    Vector3 ppos = prm._position;
                    d.GeomSetOffsetWorldPosition (prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position

                    prm.m_collisionCategories |= CollisionCategories.Body;
                    prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
                    d.GeomSetCategoryBits (prm.prim_geom, (int)prm.m_collisionCategories);
                    d.GeomSetCollideBits (prm.prim_geom, (int)prm.m_collisionFlags);

                    prm.Body = Body;
                    prm.m_disabled = false;
                    prm.m_interpenetrationcount = 0;
                    prm.m_collisionscore = 0;
                    _parent_scene.addActivePrim (prm);

                    if (prm.m_targetSpace != _parent_scene.space)
                    {
                        _parent_scene.waitForSpaceUnlock (m_targetSpace);
                        if (d.SpaceQuery (prm.m_targetSpace, prm.prim_geom))
                            d.SpaceRemove (prm.m_targetSpace, prm.prim_geom);

                        prm.m_targetSpace = _parent_scene.space;
                        d.SpaceAdd (m_targetSpace, prm.prim_geom);
                    }
                }
            }
            // The body doesn't already have a finite rotation mode set here
            if ((!m_angularlock.ApproxEquals (Vector3.One, 0.0f)) && _parent == null)
            {
                createAMotor (m_angularlock);
            }
            if (m_vehicle.Type != Vehicle.TYPE_NONE)
            {
                m_vehicle.Enable (Body, this, _parent_scene);
            }
            _parent_scene.addActivePrim (this);

            /*            d.Mass mtmp;
                        d.BodyGetMass(Body, out mtmp);
                        d.Matrix3 mt = d.GeomGetRotation(prim_geom);
                        d.Matrix3 mt2 = d.BodyGetRotation(Body);
                        dvtmp = d.GeomGetPosition(prim_geom);
                        dbtmp = d.BodyGetPosition(Body);
            */
        }
示例#3
0
 private static void DMassDup(ref d.Mass src, out d.Mass dst)
     {
     dst = new d.Mass { };
     
     dst.c.W = src.c.W;
     dst.c.X = src.c.X;
     dst.c.Y = src.c.Y;
     dst.c.Z = src.c.Z;
     dst.mass = src.mass;
     dst.I.M00 = src.I.M00;
     dst.I.M01 = src.I.M01;
     dst.I.M02 = src.I.M02;
     dst.I.M10 = src.I.M10;
     dst.I.M11 = src.I.M11;
     dst.I.M12 = src.I.M12;
     dst.I.M20 = src.I.M20;
     dst.I.M21 = src.I.M21;
     dst.I.M22 = src.I.M22;
     }