From b7baa3cd2aa60324f52118e565465475c669ec80 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Fri, 9 May 2008 07:50:00 +0000 Subject: * Valid Sculpted prim now collide properly. * The first time you set the sculpted texture of a prim you might have to futz with it to get it to generate a sculpted physics proxy * Note that there are already issues in Trunk, (such as the prim scaling issue and prim jumping issue. Essentially editing is difficult right now) * This just adds to the experimental nature of trunk. :D --- OpenSim/Region/Environment/Scenes/Scene.cs | 2 +- .../Region/Environment/Scenes/SceneObjectGroup.cs | 13 ++ .../Region/Environment/Scenes/SceneObjectPart.cs | 8 + OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 92 ++++++++---- OpenSim/Region/Physics/Meshing/SculptMesh.cs | 162 ++++++++++++++++----- 5 files changed, 209 insertions(+), 68 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 5ce3c7b..1f66744 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1134,7 +1134,7 @@ namespace OpenSim.Region.Environment.Scenes SceneObjectPart rootPart = group.GetChildPart(group.UUID); rootPart.ObjectFlags &= ~(uint)LLObject.ObjectFlags.Scripted; rootPart.TrimPermissions(); - + group.CheckSculptAndLoad(); group.ApplyPhysics(m_physicalPrim); //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 033a419..aae6af8 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -2546,5 +2546,18 @@ namespace OpenSim.Region.Environment.Scenes } return retmass; } + public void CheckSculptAndLoad() + { + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + { + if (part.Shape.SculptEntry && part.Shape.SculptTexture != LLUUID.Zero) + { + m_scene.AssetCache.GetAsset(part.Shape.SculptTexture, part.SculptTextureCallback, true); + } + } + } + } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 0075a22..9502627 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -1568,6 +1568,10 @@ namespace OpenSim.Region.Environment.Scenes byte[] extraP = new byte[Shape.ExtraParams.Length]; Array.Copy(Shape.ExtraParams, extraP, extraP.Length); dupe.Shape.ExtraParams = extraP; + if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero) + { + m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true); + } bool UsePhysics = ((dupe.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0); dupe.DoPhysicsPropertyUpdate(UsePhysics, true); @@ -1939,6 +1943,10 @@ namespace OpenSim.Region.Environment.Scenes if (texture != null) { m_shape.SculptData = texture.Data; + if (PhysActor != null) + { + PhysActor.Shape = m_shape; + } } } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 9c6dff4..1d2f986 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -1209,7 +1209,29 @@ namespace OpenSim.Region.Physics.Meshing return m; } + private SculptMesh CreateSculptMesh(string primName, PrimitiveBaseShape primShape, PhysicsVector size) + { + SculptMesh sm = new SculptMesh(primShape.SculptData); + // Scale the mesh based on our prim scale + foreach (Vertex v in sm.vertices) + { + v.X *= 0.5f; + v.Y *= 0.5f; + v.Z *= 0.5f; + v.X *= size.X; + v.Y *= size.Y; + v.Z *= size.Z; + } + // This was built with the normals pointing inside.. + // therefore we have to invert the normals + foreach (Triangle t in sm.triangles) + { + t.invertNormal(); + } + sm.DumpRaw(baseDir, primName, "Sculpt"); + return sm; + } public static void CalcNormals(Mesh mesh) { int iTriangles = mesh.triangles.Count; @@ -1317,43 +1339,53 @@ namespace OpenSim.Region.Physics.Meshing public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) { Mesh mesh = null; - - switch (primShape.ProfileShape) + if (primShape.SculptEntry && primShape.SculptType != (byte)0 && primShape.SculptData.Length > 0) { - case ProfileShape.Square: - mesh = CreateBoxMesh(primName, primShape, size); - CalcNormals(mesh); - break; - case ProfileShape.Circle: - if (primShape.PathCurve == (byte)Extrusion.Straight) - { - mesh = CreateCyllinderMesh(primName, primShape, size); - CalcNormals(mesh); - } - break; - case ProfileShape.HalfCircle: - if (primShape.PathCurve == (byte)Extrusion.Curve1) - { - mesh = CreateSphereMesh(primName, primShape, size); + SculptMesh smesh = CreateSculptMesh(primName, primShape, size); + mesh = (Mesh)smesh; + CalcNormals(mesh); + } + else + { + switch (primShape.ProfileShape) + { + case ProfileShape.Square: + mesh = CreateBoxMesh(primName, primShape, size); CalcNormals(mesh); - } - break; + break; + case ProfileShape.Circle: + if (primShape.PathCurve == (byte)Extrusion.Straight) + { + mesh = CreateCyllinderMesh(primName, primShape, size); + CalcNormals(mesh); + } + break; + case ProfileShape.HalfCircle: + if (primShape.PathCurve == (byte)Extrusion.Curve1) + { + mesh = CreateSphereMesh(primName, primShape, size); + CalcNormals(mesh); + } + break; - case ProfileShape.EquilateralTriangle: - mesh = CreatePrismMesh(primName, primShape, size); - CalcNormals(mesh); - break; + case ProfileShape.EquilateralTriangle: + mesh = CreatePrismMesh(primName, primShape, size); + CalcNormals(mesh); + break; - default: - mesh = CreateBoxMesh(primName, primShape, size); - CalcNormals(mesh); - //Set default mesh to cube otherwise it'll return - // null and crash on the 'setMesh' method in the physics plugins. - //mesh = null; - break; + default: + mesh = CreateBoxMesh(primName, primShape, size); + CalcNormals(mesh); + //Set default mesh to cube otherwise it'll return + // null and crash on the 'setMesh' method in the physics plugins. + //mesh = null; + break; + } } return mesh; } + + } } diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index ff9964e..924c4d3 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs @@ -1,3 +1,30 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + using System; using System.Collections.Generic; using System.Drawing; @@ -8,23 +35,34 @@ using Image = System.Drawing.Image; namespace OpenSim.Region.Physics.Meshing { + // This functionality based on the XNA SculptPreview by John Hurliman. public class SculptMesh : Mesh { Image idata = null; Bitmap bLOD = null; Bitmap bBitmap = null; - Vertex northpole = (Vertex)Vertex.Zero; - Vertex southpole = (Vertex)Vertex.Zero; + Vertex northpole = new Vertex(0, 0, 0); + Vertex southpole = new Vertex(0, 0, 0); - private int lod = 64; + private int lod = 32; private const float RANGE = 128.0f; public SculptMesh(byte[] jpegData) { idata = OpenJPEG.DecodeToImage(jpegData); if (idata != null) + { bBitmap = new Bitmap(idata); + if (bBitmap.Width == bBitmap.Height) + { + DoLOD(); + + LoadPoles(); + + processSculptTexture(); + } + } } @@ -37,17 +75,18 @@ namespace OpenSim.Region.Physics.Meshing } private void LoadPoles() { - northpole = (Vertex)Vertex.Zero; - for (int x = 0; x < bBitmap.Width; x++) + northpole = new Vertex(0, 0, 0); + for (int x = 0; x < bLOD.Width; x++) { northpole += ColorToVertex(GetPixel(0, 0)); } - northpole /= bBitmap.Width; + northpole /= bLOD.Width; - southpole = (Vertex)Vertex.Zero; - for (int x = 0; x < bBitmap.Width; x++) + southpole = new Vertex(0, 0, 0); + for (int x = 0; x < bLOD.Width; x++) { - southpole += ColorToVertex(GetPixel(bBitmap.Height - 1, (bBitmap.Height - 1))); + //System.Console.WriteLine("Height: " + bLOD.Height.ToString()); + southpole += ColorToVertex(GetPixel(bLOD.Height - 1, (bLOD.Height - 1))); } southpole /= bBitmap.Width; } @@ -182,12 +221,16 @@ namespace OpenSim.Region.Physics.Meshing { v1 = ColorToVertex(GetPixel(x, y)); } + // Add the vertex for use later - Add(v1); + if (!vertices.Contains(v1)) + Add(v1); + sVertices[y * COLUMNS + x] = v1; + //System.Console.WriteLine("adding: " + v1.ToString()); } - Vertex tempVertex = vertices[y * COLUMNS]; - sVertices[y * COLUMNS + x_max] = tempVertex; + //Vertex tempVertex = vertices[y * COLUMNS]; + // sVertices[y * COLUMNS + x_max] = tempVertex; } // Create the Triangles @@ -199,32 +242,77 @@ namespace OpenSim.Region.Physics.Meshing for (x = 0; x < x_max; x++) { - Triangle tri1 = new Triangle(sVertices[(y * COLUMNS + x)], sVertices[(y * COLUMNS + (x + 1))], - sVertices[((y + 1) * COLUMNS + (x + 1))]); - //indices[i++] = (ushort)(y * COLUMNS + x); - //indices[i++] = (ushort)(y * COLUMNS + (x + 1)); - //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); - Add(tri1); - Triangle tri2 = new Triangle(sVertices[(y * COLUMNS + x)],sVertices[((y + 1) * COLUMNS + (x + 1))], - sVertices[((y + 1) * COLUMNS + x)]); - - Add(tri2); - //indices[i++] = (ushort)(y * COLUMNS + x); - //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); - //indices[i++] = (ushort)((y + 1) * COLUMNS + x); + Vertex vt11 = sVertices[(y * COLUMNS + x)]; + Vertex vt12 = sVertices[(y * COLUMNS + (x + 1))]; + Vertex vt13 = sVertices[((y + 1) * COLUMNS + (x + 1))]; + if (vt11 != null && vt12 != null && vt13 != null) + { + if (vt11 != vt12 && vt11 != vt13 && vt12 != vt13) + { + Triangle tri1 = new Triangle(vt11, vt12, vt13); + //indices[i++] = (ushort)(y * COLUMNS + x); + //indices[i++] = (ushort)(y * COLUMNS + (x + 1)); + //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); + Add(tri1); + } + } + + Vertex vt21 = sVertices[(y * COLUMNS + x)]; + Vertex vt22 = sVertices[((y + 1) * COLUMNS + (x + 1))]; + Vertex vt23 = sVertices[((y + 1) * COLUMNS + x)]; + if (vt21 != null && vt22 != null && vt23 != null) + { + if (vt21.Equals(vt22, 0.022f) || vt21.Equals(vt23, 0.022f) || vt22.Equals(vt23, 0.022f)) + { + } + else + { + Triangle tri2 = new Triangle(vt21, vt22, vt23); + //indices[i++] = (ushort)(y * COLUMNS + x); + //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); + //indices[i++] = (ushort)((y + 1) * COLUMNS + x); + Add(tri2); + } + } + + } + Vertex vt31 = sVertices[(y * x_max + x)]; + Vertex vt32 = sVertices[(y * x_max + 0)]; + Vertex vt33 = sVertices[((y + 1) * x_max + 0)]; + if (vt31 != null && vt32 != null && vt33 != null) + { + if (vt31.Equals(vt32, 0.022f) || vt31.Equals(vt33, 0.022f) || vt32.Equals(vt33, 0.022f)) + { + } + else + { + //Triangle tri3 = new Triangle(vt31, vt32, vt33); + // Wrap the last cell in the row around + //indices[i++] = (ushort)(y * x_max + x); //a + //indices[i++] = (ushort)(y * x_max + 0); //b + //indices[i++] = (ushort)((y + 1) * x_max + 0); //c + //Add(tri3); + } + } + + Vertex vt41 = sVertices[(y * x_max + x)]; + Vertex vt42 = sVertices[((y + 1) * x_max + 0)]; + Vertex vt43 = sVertices[((y + 1) * x_max + x)]; + if (vt41 != null && vt42 != null && vt43 != null) + { + if (vt41.Equals(vt42, 0.022f) || vt31.Equals(vt43, 0.022f) || vt32.Equals(vt43, 0.022f)) + { + } + else + { + //Triangle tri4 = new Triangle(vt41, vt42, vt43); + //indices[i++] = (ushort)(y * x_max + x); //a + //indices[i++] = (ushort)((y + 1) * x_max + 0); //b + //indices[i++] = (ushort)((y + 1) * x_max + x); //c + //Add(tri4); + } } - Triangle tri3 = new Triangle(sVertices[(y * x_max + x)], sVertices[(y * x_max + 0)], sVertices[((y + 1) * x_max + 0)]); - Add(tri3); - // Wrap the last cell in the row around - //indices[i++] = (ushort)(y * x_max + x); //a - //indices[i++] = (ushort)(y * x_max + 0); //b - //indices[i++] = (ushort)((y + 1) * x_max + 0); //c - - Triangle tri4 = new Triangle(sVertices[(y * x_max + x)], sVertices[((y + 1) * x_max + 0)], sVertices[((y + 1) * x_max + x)]); - Add(tri4); - //indices[i++] = (ushort)(y * x_max + x); //a - //indices[i++] = (ushort)((y + 1) * x_max + 0); //b - //indices[i++] = (ushort)((y + 1) * x_max + x); //c + } } } -- cgit v1.1