// Simulate one timestep public override void Simulate(float timeStep) { int updatedEntityCount; IntPtr updatedEntitiesPtr; int collidersCount; IntPtr collidersPtr; // prevent simulation until we've been initialized if (!m_initialized) { return; } // update the prim states while we know the physics engine is not busy ProcessTaints(); // Some of the prims operate with special vehicle properties ProcessVehicles(timeStep); ProcessTaints(); // the vehicles might have added taints // step the physical world one interval m_simulationStep++; int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in // Get a value for 'now' so all the collision and update routines don't have to get their own m_simulationNowTime = Util.EnvironmentTickCount(); List <PhysicsActor> _colliders = new List <PhysicsActor>(); // If there were collisions, process them by sending the event to the prim. // Collisions must be processed before updates. if (collidersCount > 0 && !DisableCollisions) { for (int ii = 0; ii < collidersCount; ii++) { uint cA = m_collisionArray[ii].aID; uint cB = m_collisionArray[ii].bID; Vector3 point = m_collisionArray[ii].point; Vector3 normal = m_collisionArray[ii].normal; PhysicsActor c1, c2; SendCollision(cA, cB, point, normal, 0.01f, out c1); SendCollision(cB, cA, point, -normal, 0.01f, out c2); _colliders.Add(c1); _colliders.Add(c2); } //Send out all the collisions now #if (!ISWIN) foreach (PhysicsActor colID in _colliders) { if (colID != null) { colID.SendCollisions(); } } #else foreach (PhysicsActor colID in _colliders.Where(colID => colID != null)) { colID.SendCollisions(); } #endif } if (updatedEntityCount > 0) { lock (m_entProperties) m_entProperties.AddRange(m_updateArray); } }
// Simulate one timestep public override float Simulate(float timeStep) { int updatedEntityCount; IntPtr updatedEntitiesPtr; int collidersCount; IntPtr collidersPtr; // prevent simulation until we've been initialized if (!m_initialized) { return(10.0f); } // update the prim states while we know the physics engine is not busy ProcessTaints(); // Some of the prims operate with special vehicle properties ProcessVehicles(timeStep); ProcessTaints(); // the vehicles might have added taints // step the physical world one interval m_simulationStep++; int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in // Get a value for 'now' so all the collision and update routines don't have to get their own m_simulationNowTime = Util.EnvironmentTickCount(); // If there were collisions, process them by sending the event to the prim. // Collisions must be processed before updates. if (collidersCount > 0) { for (int ii = 0; ii < collidersCount; ii++) { uint cA = m_collisionArray[ii].aID; uint cB = m_collisionArray[ii].bID; Vector3 point = m_collisionArray[ii].point; Vector3 normal = m_collisionArray[ii].normal; SendCollision(cA, cB, point, normal, 0.01f); SendCollision(cB, cA, point, -normal, 0.01f); } } // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) { for (int ii = 0; ii < updatedEntityCount; ii++) { EntityProperties entprop = m_updateArray[ii]; // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); BSCharacter actor; if (m_avatars.TryGetValue(entprop.ID, out actor)) { actor.UpdateProperties(entprop); continue; } BSPrim prim; if (m_prims.TryGetValue(entprop.ID, out prim)) { prim.UpdateProperties(entprop); } } } if (m_detailedStatsStep > 0) { if ((m_simulationStep % m_detailedStatsStep) == 0) { BulletSimAPI.DumpBulletStatistics(); } } // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. return(timeStep / (numSubSteps * m_fixedTimeStep) * 1000f); }