예제 #1
0
        /// <summary>
        /// Change prim in response to a shape taint.
        /// </summary>
        private void changeshape()
        {
            m_taintshape = false;

            // Cleanup of old prim geometry and Bodies
            if (IsPhysical && Body != IntPtr.Zero)
            {
                if (childPrim)
                {
                    if (_parent != null)
                    {
                        OdePrim parent = (OdePrim)_parent;
                        parent.ChildDelink(this);
                    }
                }
                else
                {
                    disableBody();
                }
            }

            RemoveGeom();

            // we don't need to do space calculation because the client sends a position update also.
            if (_size.X <= 0) _size.X = 0.01f;
            if (_size.Y <= 0) _size.Y = 0.01f;
            if (_size.Z <= 0) _size.Z = 0.01f;
            // Construction of new prim

            IMesh mesh = null;


            if (_parent_scene.needsMeshing(_pbs))
            {
                // Don't need to re-enable body..   it's done in CreateMesh
                float meshlod = _parent_scene.meshSculptLOD;

                if (IsPhysical)
                    meshlod = _parent_scene.MeshSculptphysicalLOD;

                // createmesh returns null when it doesn't mesh.
                mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
                if (mesh == null)
                    CheckMeshAsset();
                else
                    m_assetFailed = false;
            }

            CreateGeom(m_targetSpace, mesh);
            d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
            d.Quaternion myrot = new d.Quaternion();
            //myrot.W = _orientation.w;
            myrot.W = _orientation.W;
            myrot.X = _orientation.X;
            myrot.Y = _orientation.Y;
            myrot.Z = _orientation.Z;
            d.GeomSetQuaternion(prim_geom, ref myrot);

            //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
            if (IsPhysical && Body == IntPtr.Zero)
            {
                // Re creates body on size.
                // EnableBody also does setMass()
                enableBody();
                if (Body != IntPtr.Zero)
                {
                    d.BodyEnable(Body);
                }
            }

            changeSelectedStatus();

            if (childPrim)
            {
                if (_parent is OdePrim)
                {
                    OdePrim parent = (OdePrim)_parent;
                    parent.ChildSetGeom(this);
                }
            }

            resetCollisionAccounting();
//            m_taintshape = false;
        }
예제 #2
0
        /// <summary>
        /// Make a prim subject to physics.
        /// </summary>
        private void enableBody()
        {
            // Don't enable this body if we're a child prim
            // this should be taken care of in the parent function not here
            if (!childPrim)
            {
                // Sets the geom to a body
                Body = d.BodyCreate(_parent_scene.world);

                setMass();
                d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
                d.Quaternion myrot = new d.Quaternion();
                myrot.X = _orientation.X;
                myrot.Y = _orientation.Y;
                myrot.Z = _orientation.Z;
                myrot.W = _orientation.W;
                d.BodySetQuaternion(Body, ref myrot);
                d.GeomSetBody(prim_geom, Body);

                if (m_assetFailed)
                {
                    d.GeomSetCategoryBits(prim_geom, 0);
                    d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
                }
                else
                {
                    m_collisionCategories |= CollisionCategories.Body;
                    m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
                }

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

                d.BodySetAutoDisableFlag(Body, true);
                d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
                
                // disconnect from world gravity so we can apply buoyancy
                d.BodySetGravityMode (Body, false);

                m_interpenetrationcount = 0;
                m_collisionscore = 0;
                m_disabled = false;

                // The body doesn't already have a finite rotation mode set here
                if (m_angularlock != 0 && _parent == null)
                {
                    createAMotor(m_angularlock);
                }
                if (m_vehicle.Type != Vehicle.TYPE_NONE)
                {
                    m_vehicle.Enable(Body, _parent_scene);
                }

                _parent_scene.ActivatePrim(this);
            }
        }
예제 #3
0
        /// <summary>
        /// Change prim in response to a size taint.
        /// </summary>
        private void changesize()
        {
#if SPAM
            m_log.DebugFormat("[ODE PRIM]: Called changesize");
#endif

            if (_size.X <= 0) _size.X = 0.01f;
            if (_size.Y <= 0) _size.Y = 0.01f;
            if (_size.Z <= 0) _size.Z = 0.01f;

            //kill body to rebuild
            if (IsPhysical && Body != IntPtr.Zero)
            {
                if (childPrim)
                {
                    if (_parent != null)
                    {
                        OdePrim parent = (OdePrim)_parent;
                        parent.ChildDelink(this);
                    }
                }
                else
                {
                    disableBody();
                }
            }

            if (d.SpaceQuery(m_targetSpace, prim_geom))
            {
//                _parent_scene.waitForSpaceUnlock(m_targetSpace);
                d.SpaceRemove(m_targetSpace, prim_geom);
            }

            RemoveGeom();

            // we don't need to do space calculation because the client sends a position update also.

            IMesh mesh = null;

            // Construction of new prim
            if (_parent_scene.needsMeshing(_pbs))
            {
                float meshlod = _parent_scene.meshSculptLOD;

                if (IsPhysical)
                    meshlod = _parent_scene.MeshSculptphysicalLOD;
                // Don't need to re-enable body..   it's done in SetMesh

                if (_parent_scene.needsMeshing(_pbs))
                {
                    mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
                    if (mesh == null)
                        CheckMeshAsset();
                    else
                        m_assetFailed = false;
                }
                    
            }

            CreateGeom(m_targetSpace, mesh);
            d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
            d.Quaternion myrot = new d.Quaternion();
            myrot.X = _orientation.X;
            myrot.Y = _orientation.Y;
            myrot.Z = _orientation.Z;
            myrot.W = _orientation.W;
            d.GeomSetQuaternion(prim_geom, ref myrot);

            //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
            if (IsPhysical && Body == IntPtr.Zero && !childPrim)
            {
                // Re creates body on size.
                // EnableBody also does setMass()
                enableBody();
                d.BodyEnable(Body);
            }

            changeSelectedStatus();

            if (childPrim)
            {
                if (_parent is OdePrim)
                {
                    OdePrim parent = (OdePrim)_parent;
                    parent.ChildSetGeom(this);
                }
            }
            resetCollisionAccounting();
            m_taintsize = _size;
        }
예제 #4
0
 private void rotate()
 {
     d.Quaternion myrot = new d.Quaternion();
     myrot.X = _orientation.X;
     myrot.Y = _orientation.Y;
     myrot.Z = _orientation.Z;
     myrot.W = _orientation.W;
     if (Body != IntPtr.Zero)
     {
         // KF: If this is a root prim do BodySet
         d.BodySetQuaternion(Body, ref myrot);
         if (IsPhysical)
         {
             // create or remove locks
             createAMotor(m_angularlock);
         }
     }
     else
     {
         // daughter prim, do Geom set
         d.GeomSetQuaternion(prim_geom, ref myrot);
     }
     
     resetCollisionAccounting();
     m_taintrot = _orientation;
 }
예제 #5
0
        /// <summary>
        /// Add prim in response to an add taint.
        /// </summary>
        private void changeadd()
        {
//            m_log.DebugFormat("[ODE PRIM]: Adding prim {0}", Name);
            
            int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
            IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);

            if (targetspace == IntPtr.Zero)
                targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);

            m_targetSpace = targetspace;

            IMesh mesh = null;

            if (_parent_scene.needsMeshing(_pbs))
            {
                // Don't need to re-enable body..   it's done in SetMesh
                mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
                // createmesh returns null when it's a shape that isn't a cube.
               // m_log.Debug(m_localID);
                if (mesh == null)
                    CheckMeshAsset();
                else
                    m_assetFailed = false;
            }

#if SPAM
Console.WriteLine("changeadd 1");
#endif
            CreateGeom(m_targetSpace, mesh);

            d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
            d.Quaternion myrot = new d.Quaternion();
            myrot.X = _orientation.X;
            myrot.Y = _orientation.Y;
            myrot.Z = _orientation.Z;
            myrot.W = _orientation.W;
            d.GeomSetQuaternion(prim_geom, ref myrot);

            if (IsPhysical && Body == IntPtr.Zero)
                enableBody();

            changeSelectedStatus();

            m_taintadd = false;
        }
예제 #6
0
        /// <summary>
        /// Add a child prim to this parent prim.
        /// </summary>
        /// <param name="prim">Child prim</param>
        private void AddChildPrim(OdePrim prim)
        {
            if (LocalID == prim.LocalID)
                return;

            if (Body == IntPtr.Zero)
            {
                Body = d.BodyCreate(_parent_scene.world);
                setMass();
            }

            lock (childrenPrim)
            {
                if (childrenPrim.Contains(prim))
                    return;

//                m_log.DebugFormat(
//                    "[ODE PRIM]: Linking prim {0} {1} to {2} {3}", prim.Name, prim.LocalID, Name, LocalID);

                childrenPrim.Add(prim);

                foreach (OdePrim prm in childrenPrim)
                {
                    d.Mass m2;
                    d.MassSetZero(out m2);
                    d.MassSetBoxTotal(out m2, prm.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);

                    d.Quaternion quat = new d.Quaternion();
                    quat.W = prm._orientation.W;
                    quat.X = prm._orientation.X;
                    quat.Y = prm._orientation.Y;
                    quat.Z = prm._orientation.Z;

                    d.Matrix3 mat = new d.Matrix3();
                    d.RfromQ(out mat, ref quat);
                    d.MassRotate(ref m2, ref mat);
                    d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
                    d.MassAdd(ref pMass, ref m2);
                }

                foreach (OdePrim prm in childrenPrim)
                {
                    prm.m_collisionCategories |= CollisionCategories.Body;
                    prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);

//Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name);
                    if (prm.m_assetFailed)
                    {
                        d.GeomSetCategoryBits(prm.prim_geom, 0);
                        d.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits);
                    }
                    else
                    {
                        d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
                        d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
                    }

                    d.Quaternion quat = new d.Quaternion();
                    quat.W = prm._orientation.W;
                    quat.X = prm._orientation.X;
                    quat.Y = prm._orientation.Y;
                    quat.Z = prm._orientation.Z;

                    d.Matrix3 mat = new d.Matrix3();
                    d.RfromQ(out mat, ref quat);
                    if (Body != IntPtr.Zero)
                    {
                        d.GeomSetBody(prm.prim_geom, Body);
                        prm.childPrim = true;
                        d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z);
                        //d.GeomSetOffsetPosition(prim.prim_geom,
                        //    (Position.X - prm.Position.X) - pMass.c.X,
                        //    (Position.Y - prm.Position.Y) - pMass.c.Y,
                        //    (Position.Z - prm.Position.Z) - pMass.c.Z);
                        d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat);
                        //d.GeomSetOffsetRotation(prm.prim_geom, ref mat);
                        d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
                        d.BodySetMass(Body, ref pMass);
                    }
                    else
                    {
                        m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name);
                    }

                    prm.m_interpenetrationcount = 0;
                    prm.m_collisionscore = 0;
                    prm.m_disabled = false;

                    prm.Body = Body;
                    _parent_scene.ActivatePrim(prm);
                }

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

                if (m_assetFailed)
                {
                    d.GeomSetCategoryBits(prim_geom, 0);
                    d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
                }
                else
                {
                    //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name);
                    d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
                    //Console.WriteLine(" Post GeomSetCategoryBits 2");
                    d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
                }

                d.Quaternion quat2 = new d.Quaternion();
                quat2.W = _orientation.W;
                quat2.X = _orientation.X;
                quat2.Y = _orientation.Y;
                quat2.Z = _orientation.Z;

                d.Matrix3 mat2 = new d.Matrix3();
                d.RfromQ(out mat2, ref quat2);
                d.GeomSetBody(prim_geom, Body);
                d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
                //d.GeomSetOffsetPosition(prim.prim_geom,
                //    (Position.X - prm.Position.X) - pMass.c.X,
                //    (Position.Y - prm.Position.Y) - pMass.c.Y,
                //    (Position.Z - prm.Position.Z) - pMass.c.Z);
                //d.GeomSetOffsetRotation(prim_geom, ref mat2);
                d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
                d.BodySetMass(Body, ref pMass);

                d.BodySetAutoDisableFlag(Body, true);
                d.BodySetAutoDisableSteps(Body, body_autodisable_frames);

                m_interpenetrationcount = 0;
                m_collisionscore = 0;
                m_disabled = false;

                // The body doesn't already have a finite rotation mode set here
                // or remove
                if (_parent == null)
                {
                    createAMotor(m_angularlock);
                }

                d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);

                if (m_vehicle.Type != Vehicle.TYPE_NONE)
                    m_vehicle.Enable(Body, _parent_scene);

                _parent_scene.ActivatePrim(this);
            }
        }
예제 #7
0
 } //end MoveAngular
 internal void LimitRotation(float timestep)
 {
     d.Quaternion rot = d.BodyGetQuaternion(Body);
     Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);    // rotq = rotation of object
     d.Quaternion m_rot = new d.Quaternion();
     bool changed = false;
     m_rot.X = rotq.X;
     m_rot.Y = rotq.Y;
     m_rot.Z = rotq.Z;
     m_rot.W = rotq.W;
     if (m_RollreferenceFrame != Quaternion.Identity)
     {
         if (rotq.X >= m_RollreferenceFrame.X)
         {
             m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
         }
         if (rotq.Y >= m_RollreferenceFrame.Y)
         {
             m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
         }
         if (rotq.X <= -m_RollreferenceFrame.X)
         {
             m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
         }
         if (rotq.Y <= -m_RollreferenceFrame.Y)
         {
             m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
         }
         changed = true;
     }
     if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
     {
         m_rot.X = 0;
         m_rot.Y = 0;
         changed = true;
     }
     if (changed)
         d.BodySetQuaternion(Body, ref m_rot);
 }