* 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
0.6.0-stable
Teravus Ovares 2008-05-09 07:50:00 +00:00
parent 74df815630
commit b7baa3cd2a
5 changed files with 208 additions and 67 deletions

View File

@ -1134,7 +1134,7 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectPart rootPart = group.GetChildPart(group.UUID); SceneObjectPart rootPart = group.GetChildPart(group.UUID);
rootPart.ObjectFlags &= ~(uint)LLObject.ObjectFlags.Scripted; rootPart.ObjectFlags &= ~(uint)LLObject.ObjectFlags.Scripted;
rootPart.TrimPermissions(); rootPart.TrimPermissions();
group.CheckSculptAndLoad();
group.ApplyPhysics(m_physicalPrim); group.ApplyPhysics(m_physicalPrim);
//rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
} }

View File

@ -2546,5 +2546,18 @@ namespace OpenSim.Region.Environment.Scenes
} }
return retmass; 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);
}
}
}
}
} }
} }

View File

@ -1568,6 +1568,10 @@ namespace OpenSim.Region.Environment.Scenes
byte[] extraP = new byte[Shape.ExtraParams.Length]; byte[] extraP = new byte[Shape.ExtraParams.Length];
Array.Copy(Shape.ExtraParams, extraP, extraP.Length); Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
dupe.Shape.ExtraParams = extraP; 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); bool UsePhysics = ((dupe.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
dupe.DoPhysicsPropertyUpdate(UsePhysics, true); dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
@ -1939,6 +1943,10 @@ namespace OpenSim.Region.Environment.Scenes
if (texture != null) if (texture != null)
{ {
m_shape.SculptData = texture.Data; m_shape.SculptData = texture.Data;
if (PhysActor != null)
{
PhysActor.Shape = m_shape;
}
} }
} }

View File

@ -1209,7 +1209,29 @@ namespace OpenSim.Region.Physics.Meshing
return m; 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) public static void CalcNormals(Mesh mesh)
{ {
int iTriangles = mesh.triangles.Count; int iTriangles = mesh.triangles.Count;
@ -1317,43 +1339,53 @@ namespace OpenSim.Region.Physics.Meshing
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
{ {
Mesh mesh = null; Mesh mesh = null;
if (primShape.SculptEntry && primShape.SculptType != (byte)0 && primShape.SculptData.Length > 0)
switch (primShape.ProfileShape)
{ {
case ProfileShape.Square: SculptMesh smesh = CreateSculptMesh(primName, primShape, size);
mesh = CreateBoxMesh(primName, primShape, size); mesh = (Mesh)smesh;
CalcNormals(mesh); CalcNormals(mesh);
break; }
case ProfileShape.Circle: else
if (primShape.PathCurve == (byte)Extrusion.Straight) {
{ switch (primShape.ProfileShape)
mesh = CreateCyllinderMesh(primName, primShape, size); {
case ProfileShape.Square:
mesh = CreateBoxMesh(primName, primShape, size);
CalcNormals(mesh); CalcNormals(mesh);
} break;
break; case ProfileShape.Circle:
case ProfileShape.HalfCircle: if (primShape.PathCurve == (byte)Extrusion.Straight)
if (primShape.PathCurve == (byte)Extrusion.Curve1) {
{ mesh = CreateCyllinderMesh(primName, primShape, size);
mesh = CreateSphereMesh(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); CalcNormals(mesh);
} break;
break;
case ProfileShape.EquilateralTriangle: default:
mesh = CreatePrismMesh(primName, primShape, size); mesh = CreateBoxMesh(primName, primShape, size);
CalcNormals(mesh); CalcNormals(mesh);
break; //Set default mesh to cube otherwise it'll return
// null and crash on the 'setMesh' method in the physics plugins.
default: //mesh = null;
mesh = CreateBoxMesh(primName, primShape, size); break;
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; return mesh;
} }
} }
} }

View File

@ -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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
@ -8,23 +35,34 @@ using Image = System.Drawing.Image;
namespace OpenSim.Region.Physics.Meshing namespace OpenSim.Region.Physics.Meshing
{ {
// This functionality based on the XNA SculptPreview by John Hurliman.
public class SculptMesh : Mesh public class SculptMesh : Mesh
{ {
Image idata = null; Image idata = null;
Bitmap bLOD = null; Bitmap bLOD = null;
Bitmap bBitmap = null; Bitmap bBitmap = null;
Vertex northpole = (Vertex)Vertex.Zero; Vertex northpole = new Vertex(0, 0, 0);
Vertex southpole = (Vertex)Vertex.Zero; Vertex southpole = new Vertex(0, 0, 0);
private int lod = 64; private int lod = 32;
private const float RANGE = 128.0f; private const float RANGE = 128.0f;
public SculptMesh(byte[] jpegData) public SculptMesh(byte[] jpegData)
{ {
idata = OpenJPEG.DecodeToImage(jpegData); idata = OpenJPEG.DecodeToImage(jpegData);
if (idata != null) if (idata != null)
{
bBitmap = new Bitmap(idata); bBitmap = new Bitmap(idata);
if (bBitmap.Width == bBitmap.Height)
{
DoLOD();
LoadPoles();
processSculptTexture();
}
}
} }
@ -37,17 +75,18 @@ namespace OpenSim.Region.Physics.Meshing
} }
private void LoadPoles() private void LoadPoles()
{ {
northpole = (Vertex)Vertex.Zero; northpole = new Vertex(0, 0, 0);
for (int x = 0; x < bBitmap.Width; x++) for (int x = 0; x < bLOD.Width; x++)
{ {
northpole += ColorToVertex(GetPixel(0, 0)); northpole += ColorToVertex(GetPixel(0, 0));
} }
northpole /= bBitmap.Width; northpole /= bLOD.Width;
southpole = (Vertex)Vertex.Zero; southpole = new Vertex(0, 0, 0);
for (int x = 0; x < bBitmap.Width; x++) 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; southpole /= bBitmap.Width;
} }
@ -182,12 +221,16 @@ namespace OpenSim.Region.Physics.Meshing
{ {
v1 = ColorToVertex(GetPixel(x, y)); v1 = ColorToVertex(GetPixel(x, y));
} }
// Add the vertex for use later // Add the vertex for use later
Add(v1); if (!vertices.Contains(v1))
Add(v1);
sVertices[y * COLUMNS + x] = v1; sVertices[y * COLUMNS + x] = v1;
//System.Console.WriteLine("adding: " + v1.ToString());
} }
Vertex tempVertex = vertices[y * COLUMNS]; //Vertex tempVertex = vertices[y * COLUMNS];
sVertices[y * COLUMNS + x_max] = tempVertex; // sVertices[y * COLUMNS + x_max] = tempVertex;
} }
// Create the Triangles // Create the Triangles
@ -199,32 +242,77 @@ namespace OpenSim.Region.Physics.Meshing
for (x = 0; x < x_max; x++) for (x = 0; x < x_max; x++)
{ {
Triangle tri1 = new Triangle(sVertices[(y * COLUMNS + x)], sVertices[(y * COLUMNS + (x + 1))], Vertex vt11 = sVertices[(y * COLUMNS + x)];
sVertices[((y + 1) * COLUMNS + (x + 1))]); Vertex vt12 = sVertices[(y * COLUMNS + (x + 1))];
//indices[i++] = (ushort)(y * COLUMNS + x); Vertex vt13 = sVertices[((y + 1) * COLUMNS + (x + 1))];
//indices[i++] = (ushort)(y * COLUMNS + (x + 1)); if (vt11 != null && vt12 != null && vt13 != null)
//indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); {
Add(tri1); if (vt11 != vt12 && vt11 != vt13 && vt12 != vt13)
Triangle tri2 = new Triangle(sVertices[(y * COLUMNS + x)],sVertices[((y + 1) * COLUMNS + (x + 1))], {
sVertices[((y + 1) * COLUMNS + x)]); 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);
}
}
Add(tri2); Vertex vt21 = sVertices[(y * COLUMNS + x)];
//indices[i++] = (ushort)(y * COLUMNS + x); Vertex vt22 = sVertices[((y + 1) * COLUMNS + (x + 1))];
//indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1)); Vertex vt23 = sVertices[((y + 1) * COLUMNS + x)];
//indices[i++] = (ushort)((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);
}
}
} }
Triangle tri3 = new Triangle(sVertices[(y * x_max + x)], sVertices[(y * x_max + 0)], sVertices[((y + 1) * x_max + 0)]); Vertex vt31 = sVertices[(y * x_max + x)];
Add(tri3); Vertex vt32 = sVertices[(y * x_max + 0)];
// Wrap the last cell in the row around Vertex vt33 = sVertices[((y + 1) * x_max + 0)];
//indices[i++] = (ushort)(y * x_max + x); //a if (vt31 != null && vt32 != null && vt33 != null)
//indices[i++] = (ushort)(y * x_max + 0); //b {
//indices[i++] = (ushort)((y + 1) * x_max + 0); //c if (vt31.Equals(vt32, 0.022f) || vt31.Equals(vt33, 0.022f) || vt32.Equals(vt33, 0.022f))
{
Triangle tri4 = new Triangle(sVertices[(y * x_max + x)], sVertices[((y + 1) * x_max + 0)], sVertices[((y + 1) * x_max + x)]); }
Add(tri4); else
//indices[i++] = (ushort)(y * x_max + x); //a {
//indices[i++] = (ushort)((y + 1) * x_max + 0); //b //Triangle tri3 = new Triangle(vt31, vt32, vt33);
//indices[i++] = (ushort)((y + 1) * x_max + x); //c // 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);
}
}
} }
} }
} }