/// <summary> /// Set the terrain for the physics scene. /// </summary> /// <param name="heightMap">The height values for the height map. /// Should contain enough elements to fill the region size</param> public override void SetTerrain(float[] heightMap) { OpenMetaverse.Quaternion hfOrienation; if (m_terrainBuilt) { // Detach old terrain shape and remove it, so that // only the new terrain will be attached to the terrain actor RemoteMessenger.DetachShape(m_terrainID, m_terrainShapeID); RemoteMessenger.RemoveShape(m_terrainShapeID); } else { // Send a message that creates an actor for the height map RemoteMessenger.CreateStaticActor(m_terrainID, OpenMetaverse.Vector3.Zero, OpenMetaverse.Quaternion.Identity, false); } // Create the shape for the height map hfOrienation = OpenMetaverse.Quaternion.CreateFromEulers( (float)Math.PI / 2.0f, (float)Math.PI / 2.0f, 0.0f); RemoteMessenger.AddHeightField(m_terrainShapeID, (uint)m_regionExtents.X, (uint)m_regionExtents.Y, 1.0f, 1.0f, heightMap); // Attach the height map shape to the actor RemoteMessenger.AttachShape(m_terrainID, m_terrainShapeID, RemoteConfiguration.DefaultDensity, RemoteConfiguration.DefaultFriction, RemoteConfiguration.DefaultFriction, RemoteConfiguration.DefaultRestitution, hfOrienation, OpenMetaverse.Vector3.Zero); // Indicate that the terrain has been built in the remote // physics engine m_terrainBuilt = true; }
/// <summary> /// Cleans up resources used by this scene. /// </summary> public override void Dispose() { // Indicate that the scene is no longer initialized, so that no // simulation happens while disposing is occurring m_initialized = false; // Check to see if a terrain has been set for this scene in the // remote physics engine if (m_terrainBuilt) { // Detach the old terrain shape and remove it, so that // only the new terrain will be attached to the terrain actor RemoteMessenger.DetachShape(m_terrainID, m_terrainShapeID); RemoteMessenger.RemoveShape(m_terrainShapeID); } // Log out of the remote physics engine RemoteMessenger.Logoff(RemoteConfiguration.SimulationID); // Clean up the remote messenger m_remoteMessenger.Dispose(); m_remotePacketManager.Dispose(); }
/// <summary> /// Removes the terrain height map from the physics scene. /// </summary> public override void DeleteTerrain() { // Remove the actor and the shape from the remote physics engine RemoteMessenger.RemoveActor(m_terrainID); RemoteMessenger.RemoveShape(m_terrainShapeID); }
/// <summary> /// Advances the time and state of the remote physics scene. /// </summary> /// <param name="timeStep">The amount of time by which to advance /// (in seconds)</param> /// <returns>The frame time needed to simulate the step</returns> public override float Simulate(float timeStep) { List <ActorTaintCallback> taintCallbacks; float frameTime; // Record the start time of this frame lock (m_frameTimeLock) { m_frameTimeBegin = Util.EnvironmentTickCount(); } // Update any actors that have been tainted by firing any // callbacks they have scheduled lock (m_taintListLock) { taintCallbacks = new List <ActorTaintCallback>(m_taintCallbacks); m_taintCallbacks.Clear(); } foreach (ActorTaintCallback currCallback in taintCallbacks) { currCallback(); } // Update the orientation of each avatar lock (m_avatarsLock) { foreach (RemotePhysicsAvatar currAvatar in m_avatars) { m_remoteMessenger.UpdateActorOrientation(currAvatar.LocalID, currAvatar.Orientation); // If the current avatar is on the ground, force the // velocity as it decays due to friction if (currAvatar.IsColliding) { m_remoteMessenger.UpdateActorVelocity( currAvatar.LocalID, currAvatar.TargetVelocity); } // Send any collisions and physical property updates this // avatar has to the simulator currAvatar.SendCollisions(); currAvatar.RequestPhysicsterseUpdate(); } } // Send a message to the remote physiscs simulator so that it will // simulate the timestep RemoteMessenger.AdvanceTime(timeStep); // Go through each of the primitives and send their updates to // the simulator lock (m_primitivesLock) { foreach (KeyValuePair <uint, RemotePhysicsPrimitive> prim in m_primitives) { // Send any collisions and physical property updates this // primitive has to the simulator prim.Value.SendCollisions(); //if (prim.Value.m_linkParent == null) prim.Value.RequestPhysicsterseUpdate(); } } // Update the current time & simulation step CurrentSimulationTime = Util.EnvironmentTickCount(); CurrentSimulationStep++; // Fetch the time it took to process the frame (in a thread-safe // manner) and return it lock (m_frameTimeLock) { frameTime = m_frameTime; } return(frameTime); }