Exemple #1
0
 public ODESitAvatar(ODEScene pScene, ODERayCastRequestManager raymanager)
 {
     m_scene      = pScene;
     m_raymanager = raymanager;
 }
        /// <summary>
        /// Initiailizes the scene
        /// Sets many properties that ODE requires to be stable
        /// These settings need to be tweaked 'exactly' right or weird stuff happens.
        /// </summary>
        private void Initialization()
        {
            d.AllocateODEDataForThread(~0U);

            SimulationLock = new Object();

            nearCallback = near;

            m_rayCastManager = new ODERayCastRequestManager(this);

            WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX;
            m_regionWidth = (uint)WorldExtents.X;
            WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY;
            m_regionHeight = (uint)WorldExtents.Y;

            m_suportCombine = false;

            lock (OdeLock)
            {
                // Create the world and the first space
                try
                {
                    world = d.WorldCreate();
                    TopSpace = d.HashSpaceCreate(IntPtr.Zero);

                    // now the major subspaces
                    ActiveSpace = d.HashSpaceCreate(TopSpace);
                    CharsSpace = d.HashSpaceCreate(TopSpace);
                    StaticSpace = d.HashSpaceCreate(TopSpace);
                    GroundSpace = d.HashSpaceCreate(TopSpace);
                }
                catch
                {
                    // i must RtC#FM 
                    // i did!
                }

                d.HashSpaceSetLevels(TopSpace, -5, 12);
                d.HashSpaceSetLevels(ActiveSpace, -5, 10);
                d.HashSpaceSetLevels(CharsSpace, -4, 3);
                d.HashSpaceSetLevels(StaticSpace, -5, 12);
                d.HashSpaceSetLevels(GroundSpace, 0, 8);

                // demote to second level
                d.SpaceSetSublevel(ActiveSpace, 1);
                d.SpaceSetSublevel(CharsSpace, 1);
                d.SpaceSetSublevel(StaticSpace, 1);
                d.SpaceSetSublevel(GroundSpace, 1);

                d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
                                                        CollisionCategories.Geom |
                                                        CollisionCategories.Character |
                                                        CollisionCategories.Phantom |
                                                        CollisionCategories.VolumeDtc
                                                        ));
                d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space |
                                                        CollisionCategories.Geom |
                                                        CollisionCategories.Character |
                                                        CollisionCategories.Phantom |
                                                        CollisionCategories.VolumeDtc
                                                        ));
                d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space |
                                        CollisionCategories.Geom |
                                        CollisionCategories.Character |
                                        CollisionCategories.Phantom |
                                        CollisionCategories.VolumeDtc
                                        ));
                d.GeomSetCollideBits(CharsSpace, 0);

                d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space |
                                                        CollisionCategories.Geom |
                                                        //                                                        CollisionCategories.Land |
                                                        //                                                        CollisionCategories.Water |
                                                        CollisionCategories.Phantom |
                                                        CollisionCategories.VolumeDtc
                                                        ));
                d.GeomSetCollideBits(StaticSpace, 0);

                d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land));
                d.GeomSetCollideBits(GroundSpace, 0);

                contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1);
                //contactgroup

                d.WorldSetAutoDisableFlag(world, false);
            }


            //  checkThread();


            // Defaults

            int contactsPerCollision = 80;

            physicsconfig = null;

            if (m_config != null)
            {
                physicsconfig = m_config.Configs["ODEPhysicsSettings"];
                if (physicsconfig != null)
                {
                    gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
                    gravityy = physicsconfig.GetFloat("world_gravityy", gravityy);
                    gravityz = physicsconfig.GetFloat("world_gravityz", gravityz);

                    metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace);

                    //                    contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer);

                    ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE);

                    avDensity = physicsconfig.GetFloat("av_density", avDensity);
                    avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
                    avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);

                    contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);

                    geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
                    bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);

                    physics_logging = physicsconfig.GetBoolean("physics_logging", false);
                    physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
                    physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);

                    minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset);
                    maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject);

                    avDensity *= 3f / 80f;  // scale other engines density option to this
                }
            }

            float heartbeat = 1/m_frameWorkScene.FrameTime;
            maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI;
            maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity;

            d.WorldSetCFM(world, comumContactCFM);
            d.WorldSetERP(world, comumContactERP);

            d.WorldSetGravity(world, gravityx, gravityy, gravityz);

            d.WorldSetLinearDamping(world, 0.002f);
            d.WorldSetAngularDamping(world, 0.002f);
            d.WorldSetAngularDampingThreshold(world, 0f);
            d.WorldSetLinearDampingThreshold(world, 0f);
            d.WorldSetMaxAngularSpeed(world, maximumAngularVelocity);

            d.WorldSetQuickStepNumIterations(world, m_physicsiterations);

            d.WorldSetContactSurfaceLayer(world, contactsurfacelayer);
            d.WorldSetContactMaxCorrectingVel(world, 60.0f);

            HalfOdeStep = ODE_STEPSIZE * 0.5f;
            odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f);

            ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
            GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf);

            SharedTmpcontact.geom.g1 = IntPtr.Zero;
            SharedTmpcontact.geom.g2 = IntPtr.Zero;

            SharedTmpcontact.geom.side1 = -1;
            SharedTmpcontact.geom.side2 = -1;

            SharedTmpcontact.surface.mode = comumContactFlags;
            SharedTmpcontact.surface.mu = 0;
            SharedTmpcontact.surface.bounce = 0;
            SharedTmpcontact.surface.soft_cfm = comumContactCFM;
            SharedTmpcontact.surface.soft_erp = comumContactERP;
            SharedTmpcontact.surface.slip1 = comumContactSLIP;
            SharedTmpcontact.surface.slip2 = comumContactSLIP;

            m_materialContactsData[(int)Material.Stone].mu = 0.8f;
            m_materialContactsData[(int)Material.Stone].bounce = 0.4f;

            m_materialContactsData[(int)Material.Metal].mu = 0.3f;
            m_materialContactsData[(int)Material.Metal].bounce = 0.4f;

            m_materialContactsData[(int)Material.Glass].mu = 0.2f;
            m_materialContactsData[(int)Material.Glass].bounce = 0.7f;

            m_materialContactsData[(int)Material.Wood].mu = 0.6f;
            m_materialContactsData[(int)Material.Wood].bounce = 0.5f;

            m_materialContactsData[(int)Material.Flesh].mu = 0.9f;
            m_materialContactsData[(int)Material.Flesh].bounce = 0.3f;

            m_materialContactsData[(int)Material.Plastic].mu = 0.4f;
            m_materialContactsData[(int)Material.Plastic].bounce = 0.7f;

            m_materialContactsData[(int)Material.Rubber].mu = 0.9f;
            m_materialContactsData[(int)Material.Rubber].bounce = 0.95f;

            m_materialContactsData[(int)Material.light].mu = 0.0f;
            m_materialContactsData[(int)Material.light].bounce = 0.0f;


            spacesPerMeterX = 1.0f / metersInSpace;
            spacesPerMeterY = spacesPerMeterX;
            spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX);
            spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY);

            if (spaceGridMaxX > 24)
            {
                spaceGridMaxX = 24;
                spacesPerMeterX = spaceGridMaxX / WorldExtents.X;
            }

            if (spaceGridMaxY > 24)
            {
                spaceGridMaxY = 24;
                spacesPerMeterY = spaceGridMaxY / WorldExtents.Y;
            }

            staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY];

            // create all spaces now
            int i, j;
            IntPtr newspace;

            for (i = 0; i < spaceGridMaxX; i++)
                for (j = 0; j < spaceGridMaxY; j++)
                {
                    newspace = d.HashSpaceCreate(StaticSpace);
                    d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space);
                    waitForSpaceUnlock(newspace);
                    d.SpaceSetSublevel(newspace, 2);
                    d.HashSpaceSetLevels(newspace, -2, 8);
                    d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space |
                                        CollisionCategories.Geom |
                                        CollisionCategories.Land |
                                        CollisionCategories.Water |
                                        CollisionCategories.Phantom |
                                        CollisionCategories.VolumeDtc
                                        ));
                    d.GeomSetCollideBits(newspace, 0);

                    staticPrimspace[i, j] = newspace;
                }

            // let this now be index limit
            spaceGridMaxX--;
            spaceGridMaxY--;

            // create 4 off world spaces (x<0,x>max,y<0,y>max)
            staticPrimspaceOffRegion = new IntPtr[4];

            for (i = 0; i < 4; i++)
            {
                newspace = d.HashSpaceCreate(StaticSpace);
                d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space);
                waitForSpaceUnlock(newspace);
                d.SpaceSetSublevel(newspace, 2);
                d.HashSpaceSetLevels(newspace, -2, 8);
                d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space |
                                    CollisionCategories.Geom |
                                    CollisionCategories.Land |
                                    CollisionCategories.Water |
                                    CollisionCategories.Phantom |
                                    CollisionCategories.VolumeDtc
                                    ));
                d.GeomSetCollideBits(newspace, 0);

                staticPrimspaceOffRegion[i] = newspace;
            }

            m_lastframe = DateTime.UtcNow;
            m_lastMeshExpire = m_lastframe;
        }
Exemple #3
0
 public ODESitAvatar(ODEScene pScene, ODERayCastRequestManager raymanager)
 {
     m_scene = pScene;
     m_raymanager = raymanager;
 }
        public override void Dispose()
        {
            lock (OdeLock)
            {

                if (world == IntPtr.Zero)
                    return;

                d.AllocateODEDataForThread(~0U);

                if (m_meshWorker != null)
                    m_meshWorker.Stop();

                if (m_rayCastManager != null)
                {
                    m_rayCastManager.Dispose();
                    m_rayCastManager = null;
                }

                lock (_prims)
                {
                    ChangesQueue.Clear();
                    foreach (OdePrim prm in _prims)
                    {
                        prm.DoAChange(changes.Remove, null);
                        _collisionEventPrim.Remove(prm);
                    }
                    _prims.Clear();
                }

                OdeCharacter[] chtorem;
                lock (_characters)
                {
                    chtorem = new OdeCharacter[_characters.Count];
                    _characters.CopyTo(chtorem);
                }

                ChangesQueue.Clear();
                foreach (OdeCharacter ch in chtorem)
                    ch.DoAChange(changes.Remove, null);


                foreach (IntPtr GroundGeom in RegionTerrain.Values)
                {
                    if (GroundGeom != IntPtr.Zero)
                        d.GeomDestroy(GroundGeom);
                }

                RegionTerrain.Clear();

                if (TerrainHeightFieldHeightsHandlers.Count > 0)
                {
                    foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values)
                    {
                        if (gch.IsAllocated)
                            gch.Free();
                    }
                }

                TerrainHeightFieldHeightsHandlers.Clear();
                TerrainHeightFieldHeights.Clear();

                if (ContactgeomsArray != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ContactgeomsArray);
                    ContactgeomsArray = IntPtr.Zero;
                }
                if (GlobalContactsArray != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(GlobalContactsArray);
                    GlobalContactsArray = IntPtr.Zero;
                }

                d.WorldDestroy(world);
                world = IntPtr.Zero;
                //d.CloseODE();
            }
        }