diff --git a/OpenMetaverse/Rendering/Rendering.cs b/OpenMetaverse/Rendering/Rendering.cs index 0eb3f7c4..0792d5f3 100644 --- a/OpenMetaverse/Rendering/Rendering.cs +++ b/OpenMetaverse/Rendering/Rendering.cs @@ -203,6 +203,26 @@ namespace OpenMetaverse.Rendering { public List Vertices; public List Indices; + + public SimpleMesh() + { + } + + public SimpleMesh(SimpleMesh mesh) + { + this.Indices = new List(mesh.Indices); + this.Path.Open = mesh.Path.Open; + this.Path.Points = new List(mesh.Path.Points); + this.Prim = mesh.Prim; + this.Profile.Concave = mesh.Profile.Concave; + this.Profile.Faces = new List(mesh.Profile.Faces); + this.Profile.MaxX = mesh.Profile.MaxX; + this.Profile.MinX = mesh.Profile.MinX; + this.Profile.Open = mesh.Profile.Open; + this.Profile.Positions = new List(mesh.Profile.Positions); + this.Profile.TotalOutsidePoints = mesh.Profile.TotalOutsidePoints; + this.Vertices = new List(mesh.Vertices); + } } #endregion Mesh Classes diff --git a/Programs/Simian/Extensions/Movement.cs b/Programs/Simian/Extensions/Movement.cs index 70d63472..0cad8853 100644 --- a/Programs/Simian/Extensions/Movement.cs +++ b/Programs/Simian/Extensions/Movement.cs @@ -432,7 +432,7 @@ namespace Simian.Extensions agent.Avatar.Prim.Position.Z = obj.Prim.Scale.Z * 0.5f; agent.Avatar.Prim.Position.Z += agent.Avatar.Prim.Scale.Z * 0.33f; - server.Scene.ObjectAdd(this, avObj, avObj.Prim.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, avObj, avObj.Prim.OwnerID, 0, PrimFlags.None); server.Avatars.SetDefaultAnimation(agent, Animations.SIT); server.Avatars.SendAnimations(agent); } diff --git a/Programs/Simian/Extensions/ObjectManager.cs b/Programs/Simian/Extensions/ObjectManager.cs index 48235c36..1569f17d 100644 --- a/Programs/Simian/Extensions/ObjectManager.cs +++ b/Programs/Simian/Extensions/ObjectManager.cs @@ -164,7 +164,7 @@ namespace Simian.Extensions // Add this prim to the object database SimulationObject simObj = new SimulationObject(prim, server); - server.Scene.ObjectAdd(this, simObj, agent.ID, 0, flags); + server.Scene.ObjectAddOrUpdate(this, simObj, agent.ID, 0, flags); } void ObjectAttachHandler(Packet packet, Agent agent) @@ -185,7 +185,7 @@ namespace Simian.Extensions obj.Prim.PrimData.AttachmentPoint = point == AttachmentPoint.Default ? obj.LastAttachmentPoint : point; // Send an update out to everyone - server.Scene.ObjectAdd(this, obj, agent.ID, 0, obj.Prim.Flags); + server.Scene.ObjectAddOrUpdate(this, obj, agent.ID, 0, obj.Prim.Flags); } } @@ -209,7 +209,7 @@ namespace Simian.Extensions newObj.Prim.LocalID = 0; newObj.Prim.Properties.CreationDate = DateTime.Now; - server.Scene.ObjectAdd(this, newObj, agent.ID, 0, flags); + server.Scene.ObjectAddOrUpdate(this, newObj, agent.ID, 0, flags); } else { @@ -355,7 +355,7 @@ namespace Simian.Extensions linkSet[i].Prim.ParentID = 0; } - server.Scene.ObjectAdd(this, linkSet[i], agent.ID, 0, linkSet[i].Prim.Flags); + server.Scene.ObjectAddOrUpdate(this, linkSet[i], agent.ID, 0, linkSet[i].Prim.Flags); } } @@ -395,7 +395,7 @@ namespace Simian.Extensions linkSet[i].Prim.Rotation *= linkSet[0].Prim.Rotation; } - server.Scene.ObjectAdd(this, linkSet[i], agent.ID, 0, linkSet[i].Prim.Flags); + server.Scene.ObjectAddOrUpdate(this, linkSet[i], agent.ID, 0, linkSet[i].Prim.Flags); } } @@ -523,7 +523,7 @@ namespace Simian.Extensions } } - server.Scene.ObjectAdd(this, obj, obj.Prim.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, obj, obj.Prim.OwnerID, 0, PrimFlags.None); } } } @@ -691,7 +691,7 @@ namespace Simian.Extensions obj.Prim.Rotation = rotation; obj.Prim.Scale = scale; - server.Scene.ObjectAdd(this, obj, agent.ID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, obj, agent.ID, 0, PrimFlags.None); } else { diff --git a/Programs/Simian/Extensions/Periscope.cs b/Programs/Simian/Extensions/Periscope.cs index f4d17d69..4ee02acf 100644 --- a/Programs/Simian/Extensions/Periscope.cs +++ b/Programs/Simian/Extensions/Periscope.cs @@ -72,13 +72,13 @@ namespace Simian.Extensions SimulationObject simObj = new SimulationObject(prim, server); if (MasterAgent != null) simObj.Prim.OwnerID = MasterAgent.ID; - server.Scene.ObjectAdd(this, simObj, MasterAgent.ID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, simObj, MasterAgent.ID, 0, PrimFlags.None); } void Objects_OnNewAttachment(Simulator simulator, Primitive prim, ulong regionHandle, ushort timeDilation) { SimulationObject simObj = new SimulationObject(prim, server); - server.Scene.ObjectAdd(this, simObj, MasterAgent.ID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, simObj, MasterAgent.ID, 0, PrimFlags.None); } void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation) diff --git a/Programs/Simian/Extensions/PhysicsSimple.cs b/Programs/Simian/Extensions/PhysicsSimple.cs index 20895885..2be7607b 100644 --- a/Programs/Simian/Extensions/PhysicsSimple.cs +++ b/Programs/Simian/Extensions/PhysicsSimple.cs @@ -39,7 +39,7 @@ namespace Simian.Extensions Vector3 direction = Vector3.Normalize(rayEnd - rayStart); // Get the mesh that has been transformed into world-space - SimpleMesh mesh = obj.GetWorldMesh(DetailLevel.Low, false); + SimpleMesh mesh = obj.GetWorldMesh(DetailLevel.Low, false, false); if (mesh != null) { // Iterate through all of the triangles in the mesh, doing a ray-triangle intersection @@ -411,12 +411,12 @@ namespace Simian.Extensions { // TODO: This doesn't update children prims when their parents move. "World meshes" are a bad approach in general, // the transforms should probably be applied to the mesh in the collision test - obj.GetWorldMesh(DetailLevel.Low, true); + obj.GetWorldMesh(DetailLevel.Low, true, true); } void Scene_OnObjectModify(object sender, SimulationObject obj, Primitive.ConstructionData data) { - obj.GetWorldMesh(DetailLevel.Low, true); + obj.GetWorldMesh(DetailLevel.Low, true, false); } void Scene_OnObjectTransform(object sender, SimulationObject obj, Vector3 position, Quaternion rotation, Vector3 velocity, @@ -425,7 +425,7 @@ namespace Simian.Extensions // TODO: This doesn't update children prims when their parents move. "World meshes" are a bad approach in general, // the transforms should probably be applied to the mesh in the collision test if (position != obj.Prim.Position || rotation != obj.Prim.Rotation) - obj.GetWorldMesh(DetailLevel.Low, true); + obj.GetWorldMesh(DetailLevel.Low, false, true); } #endregion Callbacks diff --git a/Programs/Simian/Extensions/SceneManager.cs b/Programs/Simian/Extensions/SceneManager.cs index 6580a9e1..cb3cfdbf 100644 --- a/Programs/Simian/Extensions/SceneManager.cs +++ b/Programs/Simian/Extensions/SceneManager.cs @@ -208,7 +208,7 @@ namespace Simian.Extensions windSpeeds[y, x] = windSpeed; } - public bool ObjectAdd(object sender, SimulationObject obj, UUID ownerID, int scriptStartParam, PrimFlags creatorFlags) + public bool ObjectAddOrUpdate(object sender, SimulationObject obj, UUID ownerID, int scriptStartParam, PrimFlags creatorFlags) { if (OnObjectAdd != null) { @@ -918,13 +918,13 @@ namespace Simian.Extensions { SimulationObject obj; if (TryGetObject(prim.ID, out obj)) - ObjectAdd(this, obj, obj.Prim.OwnerID, 0, PrimFlags.None); + ObjectAddOrUpdate(this, obj, obj.Prim.OwnerID, 0, PrimFlags.None); } void CompleteAgentMovementHandler(Packet packet, Agent agent) { // Add this avatar as an object in the scene - if (ObjectAdd(this, agent.Avatar, agent.Avatar.Prim.OwnerID, 0, PrimFlags.None)) + if (ObjectAddOrUpdate(this, agent.Avatar, agent.Avatar.Prim.OwnerID, 0, PrimFlags.None)) { // Send a response back to the client AgentMovementCompletePacket complete = new AgentMovementCompletePacket(); diff --git a/Programs/Simian/Extensions/ScriptApi.cs b/Programs/Simian/Extensions/ScriptApi.cs index 22840bc3..a563aafd 100644 --- a/Programs/Simian/Extensions/ScriptApi.cs +++ b/Programs/Simian/Extensions/ScriptApi.cs @@ -1076,7 +1076,7 @@ namespace Simian.Extensions // TODO: Apply constraints hostObject.Prim.Scale = new Vector3((float)scale.x, (float)scale.y, (float)scale.z); - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public LSL_Vector llGetScale() @@ -1090,7 +1090,7 @@ namespace Simian.Extensions hostObject.AddScriptLPS(1); hostObject.Prim.ClickAction = (ClickAction)action; - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public void llSetColor(LSL_Vector color, int face) @@ -1462,7 +1462,7 @@ namespace Simian.Extensions hostObject.Prim.SoundFlags = 1; // TODO: ??? hostObject.Prim.SoundRadius = 20; // TODO: Randomly selected - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public void llLoopSoundMaster(string sound, double volume) @@ -1502,7 +1502,7 @@ namespace Simian.Extensions hostObject.Prim.SoundFlags = 0; hostObject.Prim.SoundRadius = 0; - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public void llPreloadSound(string sound) @@ -1838,7 +1838,7 @@ namespace Simian.Extensions newObj.Prim.Rotation = llrot; } - if (server.Scene.ObjectAdd(this, newObj, hostObject.Prim.Properties.OwnerID, param, PrimFlags.None) && + if (server.Scene.ObjectAddOrUpdate(this, newObj, hostObject.Prim.Properties.OwnerID, param, PrimFlags.None) && newObj.Prim.ParentID == 0) { newParent = newObj; @@ -2510,7 +2510,7 @@ namespace Simian.Extensions (float)Utils.Clamp(alpha, 0f, 1f)); hostObject.Prim.Text = text; - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public LSL_Float llWater(LSL_Vector offset) @@ -3406,7 +3406,7 @@ namespace Simian.Extensions pTexAnim.Start = (float)start; hostObject.Prim.TextureAnim = pTexAnim; - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, LSL_Vector bottom_south_west) @@ -3754,7 +3754,7 @@ namespace Simian.Extensions hostObject.Prim.ParticleSys = prules; } - server.Scene.ObjectAdd(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, hostObject, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } public void llGroundRepel(double height, int water, double tau) @@ -5202,7 +5202,7 @@ namespace Simian.Extensions part.Prim.PrimData.PathCurve = PathCurve.Line; } - server.Scene.ObjectAdd(this, part, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, part, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } private void SetPointLight(SimulationObject part, bool light, LSL_Vector color, float intensity, float radius, float falloff) @@ -5225,7 +5225,7 @@ namespace Simian.Extensions part.Prim.Light = null; } - server.Scene.ObjectAdd(this, part, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, part, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } private LSL_Vector GetColor(SimulationObject part, int face) @@ -5528,7 +5528,7 @@ namespace Simian.Extensions prim.Prim.PrimData.ProfileBegin = Primitive.UnpackBeginCut((ushort)(50000.0 * dimple.x)); prim.Prim.PrimData.ProfileEnd = Primitive.UnpackBeginCut((ushort)(50000.0 * (1.0 - dimple.y))); - server.Scene.ObjectAdd(this, prim, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, prim, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } private void SetPrimitiveShapeParams(SimulationObject prim, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, @@ -5959,7 +5959,7 @@ namespace Simian.Extensions return; part.Prim.Scale = new Vector3((float)scale.x, (float)scale.y, (float)scale.z); - server.Scene.ObjectAdd(this, part, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); + server.Scene.ObjectAddOrUpdate(this, part, hostObject.Prim.Properties.OwnerID, 0, PrimFlags.None); } private void SetColor(SimulationObject part, LSL_Vector color, int face) diff --git a/Programs/Simian/Interfaces/ISceneProvider.cs b/Programs/Simian/Interfaces/ISceneProvider.cs index 2c9824c3..8f6ec2e5 100644 --- a/Programs/Simian/Interfaces/ISceneProvider.cs +++ b/Programs/Simian/Interfaces/ISceneProvider.cs @@ -112,7 +112,7 @@ namespace Simian uint TerrainPatchCountWidth { get; } uint TerrainPatchCountHeight { get; } - bool ObjectAdd(object sender, SimulationObject obj, UUID ownerID, int scriptStartParam, PrimFlags creatorFlags); + bool ObjectAddOrUpdate(object sender, SimulationObject obj, UUID ownerID, int scriptStartParam, PrimFlags creatorFlags); bool ObjectRemove(object sender, uint localID); bool ObjectRemove(object sender, UUID id); void ObjectTransform(object sender, SimulationObject obj, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 angularVelocity); diff --git a/Programs/Simian/SimulationObject.cs b/Programs/Simian/SimulationObject.cs index 14accd0b..38b91727 100644 --- a/Programs/Simian/SimulationObject.cs +++ b/Programs/Simian/SimulationObject.cs @@ -171,13 +171,13 @@ namespace Simian UndoSteps.Enqueue(new Primitive(Prim)); } - public SimpleMesh GetMesh(DetailLevel lod) + public SimpleMesh GetMesh(DetailLevel lod, bool forceMeshing) { int i = (int)lod; if (Meshes == null) Meshes = new SimpleMesh[4]; - if (Meshes[i] != null) + if (!forceMeshing && Meshes[i] != null) { return Meshes[i]; } @@ -189,21 +189,24 @@ namespace Simian } } - public SimpleMesh GetWorldMesh(DetailLevel lod, bool forceRebuild) + public SimpleMesh GetWorldMesh(DetailLevel lod, bool forceMeshing, bool forceTransform) { int i = (int)lod; if (WorldTransformedMeshes == null) WorldTransformedMeshes = new SimpleMesh[4]; - if (!forceRebuild && WorldTransformedMeshes[i] != null) + if (!forceMeshing && !forceTransform && WorldTransformedMeshes[i] != null) { return WorldTransformedMeshes[i]; } else { // Get the untransformed mesh - SimpleMesh mesh = Server.Mesher.GenerateSimpleMesh(Prim, lod); + SimpleMesh mesh = GetMesh(lod, forceMeshing); + + // Copy to our new mesh + SimpleMesh transformedMesh = new SimpleMesh(mesh); // Construct a matrix to transform to world space Matrix4 transform = Matrix4.Identity; @@ -221,15 +224,15 @@ namespace Simian transform *= Matrix4.CreateTranslation(Prim.Position); // Transform the mesh - for (int j = 0; j < mesh.Vertices.Count; j++) + for (int j = 0; j < transformedMesh.Vertices.Count; j++) { - Vertex vertex = mesh.Vertices[j]; + Vertex vertex = transformedMesh.Vertices[j]; vertex.Position *= transform; - mesh.Vertices[j] = vertex; + transformedMesh.Vertices[j] = vertex; } - WorldTransformedMeshes[i] = mesh; - return mesh; + WorldTransformedMeshes[i] = transformedMesh; + return transformedMesh; } }