Merge branch 'master' into vehicles
commit
70553a979e
|
@ -76,10 +76,10 @@ namespace OpenSim.Client.Linden
|
||||||
|
|
||||||
public void Initialise(IConfigSource source)
|
public void Initialise(IConfigSource source)
|
||||||
{
|
{
|
||||||
IConfig startupConfig = source.Configs["Startup"];
|
IConfig startupConfig = source.Configs["Modules"];
|
||||||
if (startupConfig != null)
|
if (startupConfig != null)
|
||||||
{
|
{
|
||||||
m_enabled = startupConfig.GetBoolean("gridmode", false);
|
m_enabled = startupConfig.GetBoolean("LLProxyLoginModule", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace OpenSim.Framework.Communications.Clients
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strBuffer = OSDParser.SerializeJsonString(args);
|
strBuffer = OSDParser.SerializeJsonString(args);
|
||||||
UTF8Encoding str = new UTF8Encoding();
|
Encoding str = Util.UTF8;
|
||||||
buffer = str.GetBytes(strBuffer);
|
buffer = str.GetBytes(strBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ namespace OpenSim.Framework.Communications.Clients
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strBuffer = OSDParser.SerializeJsonString(args);
|
strBuffer = OSDParser.SerializeJsonString(args);
|
||||||
UTF8Encoding str = new UTF8Encoding();
|
Encoding str = Util.UTF8;
|
||||||
buffer = str.GetBytes(strBuffer);
|
buffer = str.GetBytes(strBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ namespace OpenSim.Framework.Communications.Clients
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strBuffer = OSDParser.SerializeJsonString(args);
|
strBuffer = OSDParser.SerializeJsonString(args);
|
||||||
UTF8Encoding str = new UTF8Encoding();
|
Encoding str = Util.UTF8;
|
||||||
buffer = str.GetBytes(strBuffer);
|
buffer = str.GetBytes(strBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -543,7 +543,7 @@ namespace OpenSim.Framework.Communications.Clients
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strBuffer = OSDParser.SerializeJsonString(args);
|
strBuffer = OSDParser.SerializeJsonString(args);
|
||||||
UTF8Encoding str = new UTF8Encoding();
|
Encoding str = Util.UTF8;
|
||||||
buffer = str.GetBytes(strBuffer);
|
buffer = str.GetBytes(strBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -637,7 +637,7 @@ namespace OpenSim.Framework.Communications.Clients
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strBuffer = OSDParser.SerializeJsonString(args);
|
strBuffer = OSDParser.SerializeJsonString(args);
|
||||||
UTF8Encoding str = new UTF8Encoding();
|
Encoding str = Util.UTF8;
|
||||||
buffer = str.GetBytes(strBuffer);
|
buffer = str.GetBytes(strBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
LLUDPClient udpClient;
|
LLUDPClient udpClient;
|
||||||
if (clients.TryGetValue(client.AgentId, out udpClient))
|
if (clients.TryGetValue(client.AgentId, out udpClient))
|
||||||
{
|
{
|
||||||
m_log.Debug("[LLUDPSERVER]: Removing LLUDPClient for " + client.Name);
|
m_log.Debug("[LLUDPSERVER]: Removing LLUDPClient for " + client.Name + " in " + m_scene.RegionInfo.RegionName);
|
||||||
udpClient.Shutdown();
|
udpClient.Shutdown();
|
||||||
clients.Remove(client.AgentId, udpClient.RemoteEndPoint);
|
clients.Remove(client.AgentId, udpClient.RemoteEndPoint);
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Determine which agent this packet came from
|
// Determine which agent this packet came from
|
||||||
if (!clients.TryGetValue(address, out client))
|
if (!clients.TryGetValue(address, out client))
|
||||||
{
|
{
|
||||||
m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address);
|
m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,6 +668,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// Add the new client to our list of tracked clients
|
// Add the new client to our list of tracked clients
|
||||||
clients.Add(agentID, client.RemoteEndPoint, client);
|
clients.Add(agentID, client.RemoteEndPoint, client);
|
||||||
|
|
||||||
|
m_log.DebugFormat("[LLUDPSERVER]: Added new client {0} to region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend)
|
private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend)
|
||||||
|
|
|
@ -2284,9 +2284,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
foreach (SceneObjectPart p in sceneObject.Children.Values)
|
foreach (SceneObjectPart p in sceneObject.Children.Values)
|
||||||
p.LocalId = 0;
|
p.LocalId = 0;
|
||||||
|
|
||||||
if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim)
|
if ((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0)) // Attachment
|
||||||
{
|
|
||||||
if (sceneObject.RootPart.Shape.State != 0) // Attachment
|
|
||||||
{
|
{
|
||||||
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
||||||
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
||||||
|
@ -2352,7 +2350,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -308,7 +308,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return;
|
return;
|
||||||
String fileName = name + "_" + title + ".raw";
|
String fileName = name + "_" + title + ".raw";
|
||||||
String completePath = Path.Combine(path, fileName);
|
String completePath = System.IO.Path.Combine(path, fileName);
|
||||||
StreamWriter sw = new StreamWriter(completePath);
|
StreamWriter sw = new StreamWriter(completePath);
|
||||||
foreach (Triangle t in m_triangles)
|
foreach (Triangle t in m_triangles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,11 @@ namespace PrimMesher
|
||||||
Normalize();
|
Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Quat Identity()
|
||||||
|
{
|
||||||
|
return new Quat(0.0f, 0.0f, 0.0f, 1.1f);
|
||||||
|
}
|
||||||
|
|
||||||
public float Length()
|
public float Length()
|
||||||
{
|
{
|
||||||
return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
|
return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
|
||||||
|
@ -97,6 +102,15 @@ namespace PrimMesher
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Quat operator *(Quat q1, Quat q2)
|
||||||
|
{
|
||||||
|
float x = q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y;
|
||||||
|
float y = q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X;
|
||||||
|
float z = q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W;
|
||||||
|
float w = q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z;
|
||||||
|
return new Quat(x, y, z, w);
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">";
|
return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">";
|
||||||
|
@ -305,6 +319,10 @@ namespace PrimMesher
|
||||||
public Coord v2;
|
public Coord v2;
|
||||||
public Coord v3;
|
public Coord v3;
|
||||||
|
|
||||||
|
public int coordIndex1;
|
||||||
|
public int coordIndex2;
|
||||||
|
public int coordIndex3;
|
||||||
|
|
||||||
public Coord n1;
|
public Coord n1;
|
||||||
public Coord n2;
|
public Coord n2;
|
||||||
public Coord n3;
|
public Coord n3;
|
||||||
|
@ -321,6 +339,8 @@ namespace PrimMesher
|
||||||
this.v2 = new Coord();
|
this.v2 = new Coord();
|
||||||
this.v3 = new Coord();
|
this.v3 = new Coord();
|
||||||
|
|
||||||
|
this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet
|
||||||
|
|
||||||
this.n1 = new Coord();
|
this.n1 = new Coord();
|
||||||
this.n2 = new Coord();
|
this.n2 = new Coord();
|
||||||
this.n3 = new Coord();
|
this.n3 = new Coord();
|
||||||
|
@ -602,6 +622,12 @@ namespace PrimMesher
|
||||||
internal List<UVCoord> faceUVs;
|
internal List<UVCoord> faceUVs;
|
||||||
internal List<int> faceNumbers;
|
internal List<int> faceNumbers;
|
||||||
|
|
||||||
|
// use these for making individual meshes for each prim face
|
||||||
|
internal List<int> outerCoordIndices = null;
|
||||||
|
internal List<int> hollowCoordIndices = null;
|
||||||
|
internal List<int> cut1CoordIndices = null;
|
||||||
|
internal List<int> cut2CoordIndices = null;
|
||||||
|
|
||||||
internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f);
|
internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f);
|
||||||
internal Coord cutNormal1 = new Coord();
|
internal Coord cutNormal1 = new Coord();
|
||||||
internal Coord cutNormal2 = new Coord();
|
internal Coord cutNormal2 = new Coord();
|
||||||
|
@ -634,11 +660,20 @@ namespace PrimMesher
|
||||||
this.faceNumbers = new List<int>();
|
this.faceNumbers = new List<int>();
|
||||||
|
|
||||||
Coord center = new Coord(0.0f, 0.0f, 0.0f);
|
Coord center = new Coord(0.0f, 0.0f, 0.0f);
|
||||||
|
bool hasCenter = false;
|
||||||
|
|
||||||
List<Coord> hollowCoords = new List<Coord>();
|
List<Coord> hollowCoords = new List<Coord>();
|
||||||
List<Coord> hollowNormals = new List<Coord>();
|
List<Coord> hollowNormals = new List<Coord>();
|
||||||
List<float> hollowUs = new List<float>();
|
List<float> hollowUs = new List<float>();
|
||||||
|
|
||||||
|
if (calcVertexNormals)
|
||||||
|
{
|
||||||
|
this.outerCoordIndices = new List<int>();
|
||||||
|
this.hollowCoordIndices = new List<int>();
|
||||||
|
this.cut1CoordIndices = new List<int>();
|
||||||
|
this.cut2CoordIndices = new List<int>();
|
||||||
|
}
|
||||||
|
|
||||||
bool hasHollow = (hollow > 0.0f);
|
bool hasHollow = (hollow > 0.0f);
|
||||||
|
|
||||||
bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f);
|
bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f);
|
||||||
|
@ -692,6 +727,7 @@ namespace PrimMesher
|
||||||
else if (!simpleFace)
|
else if (!simpleFace)
|
||||||
{
|
{
|
||||||
this.coords.Add(center);
|
this.coords.Add(center);
|
||||||
|
hasCenter = true;
|
||||||
if (this.calcVertexNormals)
|
if (this.calcVertexNormals)
|
||||||
this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
|
this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
|
||||||
this.us.Add(0.0f);
|
this.us.Add(0.0f);
|
||||||
|
@ -736,6 +772,8 @@ namespace PrimMesher
|
||||||
this.coords.Add(newVert);
|
this.coords.Add(newVert);
|
||||||
if (this.calcVertexNormals)
|
if (this.calcVertexNormals)
|
||||||
{
|
{
|
||||||
|
this.outerCoordIndices.Add(this.coords.Count - 1);
|
||||||
|
|
||||||
if (sides < 5)
|
if (sides < 5)
|
||||||
{
|
{
|
||||||
this.vertexNormals.Add(angles.normals[i]);
|
this.vertexNormals.Add(angles.normals[i]);
|
||||||
|
@ -870,6 +908,15 @@ namespace PrimMesher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (calcVertexNormals)
|
||||||
|
{
|
||||||
|
foreach (Coord hc in hollowCoords)
|
||||||
|
{
|
||||||
|
this.coords.Add(hc);
|
||||||
|
hollowCoordIndices.Add(this.coords.Count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
this.coords.AddRange(hollowCoords);
|
this.coords.AddRange(hollowCoords);
|
||||||
|
|
||||||
if (this.calcVertexNormals)
|
if (this.calcVertexNormals)
|
||||||
|
@ -897,6 +944,12 @@ namespace PrimMesher
|
||||||
{
|
{
|
||||||
int lastOuterVertIndex = this.numOuterVerts - 1;
|
int lastOuterVertIndex = this.numOuterVerts - 1;
|
||||||
|
|
||||||
|
this.cut1CoordIndices.Add(0);
|
||||||
|
this.cut1CoordIndices.Add(this.coords.Count - 1);
|
||||||
|
|
||||||
|
this.cut2CoordIndices.Add(lastOuterVertIndex + 1);
|
||||||
|
this.cut2CoordIndices.Add(lastOuterVertIndex);
|
||||||
|
|
||||||
this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y;
|
this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y;
|
||||||
this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X);
|
this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X);
|
||||||
|
|
||||||
|
@ -935,9 +988,15 @@ namespace PrimMesher
|
||||||
this.faceNumbers.Add(-1);
|
this.faceNumbers.Add(-1);
|
||||||
for (int i = 0; i < numOuterVerts - 1; i++)
|
for (int i = 0; i < numOuterVerts - 1; i++)
|
||||||
this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum);
|
this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum);
|
||||||
|
|
||||||
|
//if (!hasHollow && !hasProfileCut)
|
||||||
|
// this.bottomFaceNumber = faceNum++;
|
||||||
|
|
||||||
this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++);
|
this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++);
|
||||||
if (sides > 4)
|
|
||||||
|
if (sides > 4 && (hasHollow || hasProfileCut))
|
||||||
faceNum++;
|
faceNum++;
|
||||||
|
|
||||||
if (hasHollow)
|
if (hasHollow)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numHollowVerts; i++)
|
for (int i = 0; i < numHollowVerts; i++)
|
||||||
|
@ -945,13 +1004,17 @@ namespace PrimMesher
|
||||||
|
|
||||||
faceNum++;
|
faceNum++;
|
||||||
}
|
}
|
||||||
|
//if (hasProfileCut || hasHollow)
|
||||||
|
// this.bottomFaceNumber = faceNum++;
|
||||||
this.bottomFaceNumber = faceNum++;
|
this.bottomFaceNumber = faceNum++;
|
||||||
|
|
||||||
if (hasHollow && hasProfileCut)
|
if (hasHollow && hasProfileCut)
|
||||||
this.faceNumbers.Add(faceNum++);
|
this.faceNumbers.Add(faceNum++);
|
||||||
for (int i = 0; i < this.faceNumbers.Count; i++)
|
for (int i = 0; i < this.faceNumbers.Count; i++)
|
||||||
if (this.faceNumbers[i] == -1)
|
if (this.faceNumbers[i] == -1)
|
||||||
this.faceNumbers[i] = faceNum++;
|
this.faceNumbers[i] = faceNum++;
|
||||||
|
|
||||||
|
|
||||||
this.numPrimFaces = faceNum;
|
this.numPrimFaces = faceNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,6 +1049,11 @@ namespace PrimMesher
|
||||||
copy.cutNormal2 = this.cutNormal2;
|
copy.cutNormal2 = this.cutNormal2;
|
||||||
copy.us.AddRange(this.us);
|
copy.us.AddRange(this.us);
|
||||||
copy.faceNumbers.AddRange(this.faceNumbers);
|
copy.faceNumbers.AddRange(this.faceNumbers);
|
||||||
|
|
||||||
|
copy.cut1CoordIndices = new List<int>(this.cut1CoordIndices);
|
||||||
|
copy.cut2CoordIndices = new List<int>(this.cut2CoordIndices);
|
||||||
|
copy.hollowCoordIndices = new List<int>(this.hollowCoordIndices);
|
||||||
|
copy.outerCoordIndices = new List<int>(this.outerCoordIndices);
|
||||||
}
|
}
|
||||||
copy.numOuterVerts = this.numOuterVerts;
|
copy.numOuterVerts = this.numOuterVerts;
|
||||||
copy.numHollowVerts = this.numHollowVerts;
|
copy.numHollowVerts = this.numHollowVerts;
|
||||||
|
@ -1149,17 +1217,213 @@ namespace PrimMesher
|
||||||
|
|
||||||
public struct PathNode
|
public struct PathNode
|
||||||
{
|
{
|
||||||
public float position;
|
public Coord position;
|
||||||
public Quat rotation;
|
public Quat rotation;
|
||||||
public float xScale;
|
public float xScale;
|
||||||
public float yScale;
|
public float yScale;
|
||||||
|
public float percentOfPath;
|
||||||
|
}
|
||||||
|
|
||||||
public PathNode(float position, Quat rotation, float xScale, float yScale)
|
public enum PathType { Linear = 0, Circular = 1, Flexible = 2 }
|
||||||
|
|
||||||
|
public class Path
|
||||||
{
|
{
|
||||||
this.position = position;
|
public List<PathNode> pathNodes = new List<PathNode>();
|
||||||
this.rotation = rotation;
|
|
||||||
this.xScale = xScale;
|
public float twistBegin = 0.0f;
|
||||||
this.yScale = yScale;
|
public float twistEnd = 0.0f;
|
||||||
|
public float topShearX = 0.0f;
|
||||||
|
public float topShearY = 0.0f;
|
||||||
|
public float pathCutBegin = 0.0f;
|
||||||
|
public float pathCutEnd = 1.0f;
|
||||||
|
public float dimpleBegin = 0.0f;
|
||||||
|
public float dimpleEnd = 1.0f;
|
||||||
|
public float skew = 0.0f;
|
||||||
|
public float holeSizeX = 1.0f; // called pathScaleX in pbs
|
||||||
|
public float holeSizeY = 0.25f;
|
||||||
|
public float taperX = 0.0f;
|
||||||
|
public float taperY = 0.0f;
|
||||||
|
public float radius = 0.0f;
|
||||||
|
public float revolutions = 1.0f;
|
||||||
|
public int stepsPerRevolution = 24;
|
||||||
|
|
||||||
|
private const float twoPi = 2.0f * (float)Math.PI;
|
||||||
|
|
||||||
|
public void Create(PathType pathType, int steps)
|
||||||
|
{
|
||||||
|
if (pathType == PathType.Linear || pathType == PathType.Flexible)
|
||||||
|
{
|
||||||
|
int step = 0;
|
||||||
|
|
||||||
|
float length = this.pathCutEnd - this.pathCutBegin;
|
||||||
|
float twistTotal = twistEnd - twistBegin;
|
||||||
|
float twistTotalAbs = Math.Abs(twistTotal);
|
||||||
|
if (twistTotalAbs > 0.01f)
|
||||||
|
steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
|
||||||
|
|
||||||
|
float start = -0.5f;
|
||||||
|
float stepSize = length / (float)steps;
|
||||||
|
float percentOfPathMultiplier = stepSize;
|
||||||
|
float xOffset = 0.0f;
|
||||||
|
float yOffset = 0.0f;
|
||||||
|
float zOffset = start;
|
||||||
|
float xOffsetStepIncrement = this.topShearX / steps;
|
||||||
|
float yOffsetStepIncrement = this.topShearY / steps;
|
||||||
|
|
||||||
|
float percentOfPath = this.pathCutBegin;
|
||||||
|
zOffset += percentOfPath;
|
||||||
|
|
||||||
|
// sanity checks
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
PathNode newNode = new PathNode();
|
||||||
|
|
||||||
|
newNode.xScale = 1.0f;
|
||||||
|
if (this.taperX == 0.0f)
|
||||||
|
newNode.xScale = 1.0f;
|
||||||
|
else if (this.taperX > 0.0f)
|
||||||
|
newNode.xScale = 1.0f - percentOfPath * this.taperX;
|
||||||
|
else newNode.xScale = 1.0f + (1.0f - percentOfPath) * this.taperX;
|
||||||
|
|
||||||
|
newNode.yScale = 1.0f;
|
||||||
|
if (this.taperY == 0.0f)
|
||||||
|
newNode.yScale = 1.0f;
|
||||||
|
else if (this.taperY > 0.0f)
|
||||||
|
newNode.yScale = 1.0f - percentOfPath * this.taperY;
|
||||||
|
else newNode.yScale = 1.0f + (1.0f - percentOfPath) * this.taperY;
|
||||||
|
|
||||||
|
float twist = twistBegin + twistTotal * percentOfPath;
|
||||||
|
|
||||||
|
newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist);
|
||||||
|
newNode.position = new Coord(xOffset, yOffset, zOffset);
|
||||||
|
newNode.percentOfPath = percentOfPath;
|
||||||
|
|
||||||
|
pathNodes.Add(newNode);
|
||||||
|
|
||||||
|
if (step < steps)
|
||||||
|
{
|
||||||
|
step += 1;
|
||||||
|
percentOfPath += percentOfPathMultiplier;
|
||||||
|
xOffset += xOffsetStepIncrement;
|
||||||
|
yOffset += yOffsetStepIncrement;
|
||||||
|
zOffset += stepSize;
|
||||||
|
if (percentOfPath > this.pathCutEnd)
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
else done = true;
|
||||||
|
}
|
||||||
|
} // end of linear path code
|
||||||
|
|
||||||
|
else // pathType == Circular
|
||||||
|
{
|
||||||
|
float twistTotal = twistEnd - twistBegin;
|
||||||
|
|
||||||
|
// if the profile has a lot of twist, add more layers otherwise the layers may overlap
|
||||||
|
// and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
|
||||||
|
// accurately match the viewer
|
||||||
|
float twistTotalAbs = Math.Abs(twistTotal);
|
||||||
|
if (twistTotalAbs > 0.01f)
|
||||||
|
{
|
||||||
|
if (twistTotalAbs > Math.PI * 1.5f)
|
||||||
|
steps *= 2;
|
||||||
|
if (twistTotalAbs > Math.PI * 3.0f)
|
||||||
|
steps *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
float yPathScale = this.holeSizeY * 0.5f;
|
||||||
|
float pathLength = this.pathCutEnd - this.pathCutBegin;
|
||||||
|
float totalSkew = this.skew * 2.0f * pathLength;
|
||||||
|
float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew;
|
||||||
|
float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY));
|
||||||
|
float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f;
|
||||||
|
|
||||||
|
// It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
|
||||||
|
// angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
|
||||||
|
// to calculate the sine for generating the path radius appears to approximate it's effects there
|
||||||
|
// too, but there are some subtle differences in the radius which are noticeable as the prim size
|
||||||
|
// increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
|
||||||
|
// the meshes generated with this technique appear nearly identical in shape to the same prims when
|
||||||
|
// displayed by the viewer.
|
||||||
|
|
||||||
|
float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f;
|
||||||
|
float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f;
|
||||||
|
float stepSize = twoPi / this.stepsPerRevolution;
|
||||||
|
|
||||||
|
int step = (int)(startAngle / stepSize);
|
||||||
|
int firstStep = step;
|
||||||
|
float angle = startAngle;
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
while (!done) // loop through the length of the path and add the layers
|
||||||
|
{
|
||||||
|
PathNode newNode = new PathNode();
|
||||||
|
|
||||||
|
float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX;
|
||||||
|
float yProfileScale = this.holeSizeY;
|
||||||
|
|
||||||
|
float percentOfPath = angle / (twoPi * this.revolutions);
|
||||||
|
float percentOfAngles = (angle - startAngle) / (endAngle - startAngle);
|
||||||
|
|
||||||
|
if (this.taperX > 0.01f)
|
||||||
|
xProfileScale *= 1.0f - percentOfPath * this.taperX;
|
||||||
|
else if (this.taperX < -0.01f)
|
||||||
|
xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX;
|
||||||
|
|
||||||
|
if (this.taperY > 0.01f)
|
||||||
|
yProfileScale *= 1.0f - percentOfPath * this.taperY;
|
||||||
|
else if (this.taperY < -0.01f)
|
||||||
|
yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY;
|
||||||
|
|
||||||
|
newNode.xScale = xProfileScale;
|
||||||
|
newNode.yScale = yProfileScale;
|
||||||
|
|
||||||
|
float radiusScale = 1.0f;
|
||||||
|
if (this.radius > 0.001f)
|
||||||
|
radiusScale = 1.0f - this.radius * percentOfPath;
|
||||||
|
else if (this.radius < 0.001f)
|
||||||
|
radiusScale = 1.0f + this.radius * (1.0f - percentOfPath);
|
||||||
|
|
||||||
|
float twist = twistBegin + twistTotal * percentOfPath;
|
||||||
|
|
||||||
|
float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles);
|
||||||
|
xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor;
|
||||||
|
|
||||||
|
float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale;
|
||||||
|
|
||||||
|
float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale;
|
||||||
|
|
||||||
|
newNode.position = new Coord(xOffset, yOffset, zOffset);
|
||||||
|
|
||||||
|
// now orient the rotation of the profile layer relative to it's position on the path
|
||||||
|
// adding taperY to the angle used to generate the quat appears to approximate the viewer
|
||||||
|
|
||||||
|
newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY);
|
||||||
|
|
||||||
|
// next apply twist rotation to the profile layer
|
||||||
|
if (twistTotal != 0.0f || twistBegin != 0.0f)
|
||||||
|
newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist);
|
||||||
|
|
||||||
|
newNode.percentOfPath = percentOfPath;
|
||||||
|
|
||||||
|
pathNodes.Add(newNode);
|
||||||
|
|
||||||
|
// calculate terms for next iteration
|
||||||
|
// calculate the angle for the next iteration of the loop
|
||||||
|
|
||||||
|
if (angle >= endAngle - 0.01)
|
||||||
|
done = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
step += 1;
|
||||||
|
angle = stepSize * step;
|
||||||
|
if (angle > endAngle)
|
||||||
|
angle = endAngle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1276,6 +1540,447 @@ namespace PrimMesher
|
||||||
this.hasHollow = (this.hollow > 0.001f);
|
this.hasHollow = (this.hollow > 0.001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
|
||||||
|
/// </summary>
|
||||||
|
public void Extrude(PathType pathType)
|
||||||
|
{
|
||||||
|
this.coords = new List<Coord>();
|
||||||
|
this.faces = new List<Face>();
|
||||||
|
|
||||||
|
if (this.viewerMode)
|
||||||
|
{
|
||||||
|
this.viewerFaces = new List<ViewerFace>();
|
||||||
|
this.calcVertexNormals = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.calcVertexNormals)
|
||||||
|
this.normals = new List<Coord>();
|
||||||
|
|
||||||
|
//int step = 0;
|
||||||
|
int steps = 1;
|
||||||
|
|
||||||
|
float length = this.pathCutEnd - this.pathCutBegin;
|
||||||
|
normalsProcessed = false;
|
||||||
|
|
||||||
|
if (this.viewerMode && this.sides == 3)
|
||||||
|
{
|
||||||
|
// prisms don't taper well so add some vertical resolution
|
||||||
|
// other prims may benefit from this but just do prisms for now
|
||||||
|
if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01)
|
||||||
|
steps = (int)(steps * 4.5 * length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float twistBegin = this.twistBegin / 360.0f * twoPi;
|
||||||
|
float twistEnd = this.twistEnd / 360.0f * twoPi;
|
||||||
|
float twistTotal = twistEnd - twistBegin;
|
||||||
|
float twistTotalAbs = Math.Abs(twistTotal);
|
||||||
|
if (twistTotalAbs > 0.01f)
|
||||||
|
steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
|
||||||
|
|
||||||
|
//float start = -0.5f;
|
||||||
|
//float stepSize = length / (float)steps;
|
||||||
|
//float percentOfPathMultiplier = stepSize;
|
||||||
|
//float xProfileScale = 1.0f;
|
||||||
|
//float yProfileScale = 1.0f;
|
||||||
|
//float xOffset = 0.0f;
|
||||||
|
//float yOffset = 0.0f;
|
||||||
|
//float zOffset = start;
|
||||||
|
//float xOffsetStepIncrement = this.topShearX / steps;
|
||||||
|
//float yOffsetStepIncrement = this.topShearY / steps;
|
||||||
|
|
||||||
|
//float percentOfPath = this.pathCutBegin;
|
||||||
|
//zOffset += percentOfPath;
|
||||||
|
|
||||||
|
float hollow = this.hollow;
|
||||||
|
|
||||||
|
// sanity checks
|
||||||
|
float initialProfileRot = 0.0f;
|
||||||
|
if (pathType == PathType.Circular)
|
||||||
|
{
|
||||||
|
if (this.sides == 3)
|
||||||
|
{
|
||||||
|
initialProfileRot = (float)Math.PI;
|
||||||
|
if (this.hollowSides == 4)
|
||||||
|
{
|
||||||
|
if (hollow > 0.7f)
|
||||||
|
hollow = 0.7f;
|
||||||
|
hollow *= 0.707f;
|
||||||
|
}
|
||||||
|
else hollow *= 0.5f;
|
||||||
|
}
|
||||||
|
else if (this.sides == 4)
|
||||||
|
{
|
||||||
|
initialProfileRot = 0.25f * (float)Math.PI;
|
||||||
|
if (this.hollowSides != 4)
|
||||||
|
hollow *= 0.707f;
|
||||||
|
}
|
||||||
|
else if (this.sides > 4)
|
||||||
|
{
|
||||||
|
initialProfileRot = (float)Math.PI;
|
||||||
|
if (this.hollowSides == 4)
|
||||||
|
{
|
||||||
|
if (hollow > 0.7f)
|
||||||
|
hollow = 0.7f;
|
||||||
|
hollow /= 0.7f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this.sides == 3)
|
||||||
|
{
|
||||||
|
if (this.hollowSides == 4)
|
||||||
|
{
|
||||||
|
if (hollow > 0.7f)
|
||||||
|
hollow = 0.7f;
|
||||||
|
hollow *= 0.707f;
|
||||||
|
}
|
||||||
|
else hollow *= 0.5f;
|
||||||
|
}
|
||||||
|
else if (this.sides == 4)
|
||||||
|
{
|
||||||
|
initialProfileRot = 1.25f * (float)Math.PI;
|
||||||
|
if (this.hollowSides != 4)
|
||||||
|
hollow *= 0.707f;
|
||||||
|
}
|
||||||
|
else if (this.sides == 24 && this.hollowSides == 4)
|
||||||
|
hollow *= 1.414f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals);
|
||||||
|
this.errorMessage = profile.errorMessage;
|
||||||
|
|
||||||
|
this.numPrimFaces = profile.numPrimFaces;
|
||||||
|
|
||||||
|
int cut1Vert = -1;
|
||||||
|
int cut2Vert = -1;
|
||||||
|
if (hasProfileCut)
|
||||||
|
{
|
||||||
|
cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
|
||||||
|
cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (initialProfileRot != 0.0f)
|
||||||
|
{
|
||||||
|
profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
|
||||||
|
if (viewerMode)
|
||||||
|
profile.MakeFaceUVs();
|
||||||
|
}
|
||||||
|
|
||||||
|
Coord lastCutNormal1 = new Coord();
|
||||||
|
Coord lastCutNormal2 = new Coord();
|
||||||
|
float lastV = 1.0f;
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
path.twistBegin = twistBegin;
|
||||||
|
path.twistEnd = twistEnd;
|
||||||
|
path.topShearX = topShearX;
|
||||||
|
path.topShearY = topShearY;
|
||||||
|
path.pathCutBegin = pathCutBegin;
|
||||||
|
path.pathCutEnd = pathCutEnd;
|
||||||
|
path.dimpleBegin = dimpleBegin;
|
||||||
|
path.dimpleEnd = dimpleEnd;
|
||||||
|
path.skew = skew;
|
||||||
|
path.holeSizeX = holeSizeX;
|
||||||
|
path.holeSizeY = holeSizeY;
|
||||||
|
path.taperX = taperX;
|
||||||
|
path.taperY = taperY;
|
||||||
|
path.radius = radius;
|
||||||
|
path.revolutions = revolutions;
|
||||||
|
path.stepsPerRevolution = stepsPerRevolution;
|
||||||
|
|
||||||
|
path.Create(pathType, steps);
|
||||||
|
/*
|
||||||
|
public int twistBegin = 0;
|
||||||
|
public int twistEnd = 0;
|
||||||
|
public float topShearX = 0.0f;
|
||||||
|
public float topShearY = 0.0f;
|
||||||
|
public float pathCutBegin = 0.0f;
|
||||||
|
public float pathCutEnd = 1.0f;
|
||||||
|
public float dimpleBegin = 0.0f;
|
||||||
|
public float dimpleEnd = 1.0f;
|
||||||
|
public float skew = 0.0f;
|
||||||
|
public float holeSizeX = 1.0f; // called pathScaleX in pbs
|
||||||
|
public float holeSizeY = 0.25f;
|
||||||
|
public float taperX = 0.0f;
|
||||||
|
public float taperY = 0.0f;
|
||||||
|
public float radius = 0.0f;
|
||||||
|
public float revolutions = 1.0f;
|
||||||
|
public int stepsPerRevolution = 24;
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool needEndFaces = false;
|
||||||
|
if (pathType == PathType.Circular)
|
||||||
|
{
|
||||||
|
needEndFaces = false;
|
||||||
|
if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f)
|
||||||
|
needEndFaces = true;
|
||||||
|
else if (this.taperX != 0.0f || this.taperY != 0.0f)
|
||||||
|
needEndFaces = true;
|
||||||
|
else if (this.skew != 0.0f)
|
||||||
|
needEndFaces = true;
|
||||||
|
else if (twistTotal != 0.0f)
|
||||||
|
needEndFaces = true;
|
||||||
|
else if (this.radius != 0.0f)
|
||||||
|
needEndFaces = true;
|
||||||
|
}
|
||||||
|
else needEndFaces = true;
|
||||||
|
|
||||||
|
for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++)
|
||||||
|
{
|
||||||
|
PathNode node = path.pathNodes[nodeIndex];
|
||||||
|
Profile newLayer = profile.Copy();
|
||||||
|
newLayer.Scale(node.xScale, node.yScale);
|
||||||
|
|
||||||
|
newLayer.AddRot(node.rotation);
|
||||||
|
newLayer.AddPos(node.position);
|
||||||
|
|
||||||
|
if (needEndFaces && nodeIndex == 0)
|
||||||
|
{
|
||||||
|
newLayer.FlipNormals();
|
||||||
|
|
||||||
|
// add the top faces to the viewerFaces list here
|
||||||
|
if (this.viewerMode)
|
||||||
|
{
|
||||||
|
Coord faceNormal = newLayer.faceNormal;
|
||||||
|
ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber);
|
||||||
|
int numFaces = newLayer.faces.Count;
|
||||||
|
List<Face> faces = newLayer.faces;
|
||||||
|
|
||||||
|
for (int i = 0; i < numFaces; i++)
|
||||||
|
{
|
||||||
|
Face face = faces[i];
|
||||||
|
newViewerFace.v1 = newLayer.coords[face.v1];
|
||||||
|
newViewerFace.v2 = newLayer.coords[face.v2];
|
||||||
|
newViewerFace.v3 = newLayer.coords[face.v3];
|
||||||
|
|
||||||
|
newViewerFace.coordIndex1 = face.v1;
|
||||||
|
newViewerFace.coordIndex2 = face.v2;
|
||||||
|
newViewerFace.coordIndex3 = face.v3;
|
||||||
|
|
||||||
|
newViewerFace.n1 = faceNormal;
|
||||||
|
newViewerFace.n2 = faceNormal;
|
||||||
|
newViewerFace.n3 = faceNormal;
|
||||||
|
|
||||||
|
newViewerFace.uv1 = newLayer.faceUVs[face.v1];
|
||||||
|
newViewerFace.uv2 = newLayer.faceUVs[face.v2];
|
||||||
|
newViewerFace.uv3 = newLayer.faceUVs[face.v3];
|
||||||
|
|
||||||
|
this.viewerFaces.Add(newViewerFace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // if (nodeIndex == 0)
|
||||||
|
|
||||||
|
// append this layer
|
||||||
|
|
||||||
|
int coordsLen = this.coords.Count;
|
||||||
|
int lastCoordsLen = coordsLen;
|
||||||
|
newLayer.AddValue2FaceVertexIndices(coordsLen);
|
||||||
|
|
||||||
|
this.coords.AddRange(newLayer.coords);
|
||||||
|
|
||||||
|
if (this.calcVertexNormals)
|
||||||
|
{
|
||||||
|
newLayer.AddValue2FaceNormalIndices(this.normals.Count);
|
||||||
|
this.normals.AddRange(newLayer.vertexNormals);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.percentOfPath < this.pathCutBegin + 0.01f || node.percentOfPath > this.pathCutEnd - 0.01f)
|
||||||
|
this.faces.AddRange(newLayer.faces);
|
||||||
|
|
||||||
|
// fill faces between layers
|
||||||
|
|
||||||
|
int numVerts = newLayer.coords.Count;
|
||||||
|
Face newFace = new Face();
|
||||||
|
|
||||||
|
//if (step > 0)
|
||||||
|
if (nodeIndex > 0)
|
||||||
|
{
|
||||||
|
int startVert = coordsLen + 1;
|
||||||
|
int endVert = this.coords.Count;
|
||||||
|
|
||||||
|
if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
|
||||||
|
startVert--;
|
||||||
|
|
||||||
|
for (int i = startVert; i < endVert; i++)
|
||||||
|
{
|
||||||
|
int iNext = i + 1;
|
||||||
|
if (i == endVert - 1)
|
||||||
|
iNext = startVert;
|
||||||
|
|
||||||
|
int whichVert = i - startVert;
|
||||||
|
//int whichVert2 = i - lastCoordsLen;
|
||||||
|
|
||||||
|
newFace.v1 = i;
|
||||||
|
newFace.v2 = i - numVerts;
|
||||||
|
newFace.v3 = iNext - numVerts;
|
||||||
|
this.faces.Add(newFace);
|
||||||
|
|
||||||
|
newFace.v2 = iNext - numVerts;
|
||||||
|
newFace.v3 = iNext;
|
||||||
|
this.faces.Add(newFace);
|
||||||
|
|
||||||
|
if (this.viewerMode)
|
||||||
|
{
|
||||||
|
// add the side faces to the list of viewerFaces here
|
||||||
|
|
||||||
|
int primFaceNum = profile.faceNumbers[whichVert];
|
||||||
|
if (!needEndFaces)
|
||||||
|
primFaceNum -= 1;
|
||||||
|
|
||||||
|
ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
|
||||||
|
ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
|
||||||
|
|
||||||
|
float u1 = newLayer.us[whichVert];
|
||||||
|
float u2 = 1.0f;
|
||||||
|
if (whichVert < newLayer.us.Count - 1)
|
||||||
|
u2 = newLayer.us[whichVert + 1];
|
||||||
|
|
||||||
|
if (whichVert == cut1Vert || whichVert == cut2Vert)
|
||||||
|
{
|
||||||
|
u1 = 0.0f;
|
||||||
|
u2 = 1.0f;
|
||||||
|
}
|
||||||
|
else if (sides < 5)
|
||||||
|
{
|
||||||
|
if (whichVert < profile.numOuterVerts)
|
||||||
|
{ // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
|
||||||
|
// to reflect the entire texture width
|
||||||
|
u1 *= sides;
|
||||||
|
u2 *= sides;
|
||||||
|
u2 -= (int)u1;
|
||||||
|
u1 -= (int)u1;
|
||||||
|
if (u2 < 0.1f)
|
||||||
|
u2 = 1.0f;
|
||||||
|
}
|
||||||
|
else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1)
|
||||||
|
{
|
||||||
|
u1 *= 2.0f;
|
||||||
|
u2 *= 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newViewerFace1.uv1.U = u1;
|
||||||
|
newViewerFace1.uv2.U = u1;
|
||||||
|
newViewerFace1.uv3.U = u2;
|
||||||
|
|
||||||
|
newViewerFace1.uv1.V = 1.0f - node.percentOfPath;
|
||||||
|
newViewerFace1.uv2.V = lastV;
|
||||||
|
newViewerFace1.uv3.V = lastV;
|
||||||
|
|
||||||
|
newViewerFace2.uv1.U = u1;
|
||||||
|
newViewerFace2.uv2.U = u2;
|
||||||
|
newViewerFace2.uv3.U = u2;
|
||||||
|
|
||||||
|
newViewerFace2.uv1.V = 1.0f - node.percentOfPath;
|
||||||
|
newViewerFace2.uv2.V = lastV;
|
||||||
|
newViewerFace2.uv3.V = 1.0f - node.percentOfPath;
|
||||||
|
|
||||||
|
newViewerFace1.v1 = this.coords[i];
|
||||||
|
newViewerFace1.v2 = this.coords[i - numVerts];
|
||||||
|
newViewerFace1.v3 = this.coords[iNext - numVerts];
|
||||||
|
|
||||||
|
newViewerFace2.v1 = this.coords[i];
|
||||||
|
newViewerFace2.v2 = this.coords[iNext - numVerts];
|
||||||
|
newViewerFace2.v3 = this.coords[iNext];
|
||||||
|
|
||||||
|
newViewerFace1.coordIndex1 = i;
|
||||||
|
newViewerFace1.coordIndex2 = i - numVerts;
|
||||||
|
newViewerFace1.coordIndex3 = iNext - numVerts;
|
||||||
|
|
||||||
|
newViewerFace2.coordIndex1 = i;
|
||||||
|
newViewerFace2.coordIndex2 = iNext - numVerts;
|
||||||
|
newViewerFace2.coordIndex3 = iNext;
|
||||||
|
|
||||||
|
// profile cut faces
|
||||||
|
if (whichVert == cut1Vert)
|
||||||
|
{
|
||||||
|
newViewerFace1.n1 = newLayer.cutNormal1;
|
||||||
|
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
|
||||||
|
|
||||||
|
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
|
||||||
|
newViewerFace2.n2 = lastCutNormal1;
|
||||||
|
}
|
||||||
|
else if (whichVert == cut2Vert)
|
||||||
|
{
|
||||||
|
newViewerFace1.n1 = newLayer.cutNormal2;
|
||||||
|
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
|
||||||
|
|
||||||
|
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
|
||||||
|
newViewerFace2.n2 = lastCutNormal2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else // outer and hollow faces
|
||||||
|
{
|
||||||
|
if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
|
||||||
|
{ // looks terrible when path is twisted... need vertex normals here
|
||||||
|
newViewerFace1.CalcSurfaceNormal();
|
||||||
|
newViewerFace2.CalcSurfaceNormal();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newViewerFace1.n1 = this.normals[i];
|
||||||
|
newViewerFace1.n2 = this.normals[i - numVerts];
|
||||||
|
newViewerFace1.n3 = this.normals[iNext - numVerts];
|
||||||
|
|
||||||
|
newViewerFace2.n1 = this.normals[i];
|
||||||
|
newViewerFace2.n2 = this.normals[iNext - numVerts];
|
||||||
|
newViewerFace2.n3 = this.normals[iNext];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.viewerFaces.Add(newViewerFace1);
|
||||||
|
this.viewerFaces.Add(newViewerFace2);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCutNormal1 = newLayer.cutNormal1;
|
||||||
|
lastCutNormal2 = newLayer.cutNormal2;
|
||||||
|
lastV = 1.0f - node.percentOfPath;
|
||||||
|
|
||||||
|
if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode)
|
||||||
|
{
|
||||||
|
// add the top faces to the viewerFaces list here
|
||||||
|
Coord faceNormal = newLayer.faceNormal;
|
||||||
|
ViewerFace newViewerFace = new ViewerFace();
|
||||||
|
newViewerFace.primFaceNumber = 0;
|
||||||
|
int numFaces = newLayer.faces.Count;
|
||||||
|
List<Face> faces = newLayer.faces;
|
||||||
|
|
||||||
|
for (int i = 0; i < numFaces; i++)
|
||||||
|
{
|
||||||
|
Face face = faces[i];
|
||||||
|
newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
|
||||||
|
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
|
||||||
|
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
|
||||||
|
|
||||||
|
newViewerFace.coordIndex1 = face.v1 - coordsLen;
|
||||||
|
newViewerFace.coordIndex2 = face.v2 - coordsLen;
|
||||||
|
newViewerFace.coordIndex3 = face.v3 - coordsLen;
|
||||||
|
|
||||||
|
newViewerFace.n1 = faceNormal;
|
||||||
|
newViewerFace.n2 = faceNormal;
|
||||||
|
newViewerFace.n3 = faceNormal;
|
||||||
|
|
||||||
|
newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
|
||||||
|
newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
|
||||||
|
newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
|
||||||
|
|
||||||
|
this.viewerFaces.Add(newViewerFace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
|
/// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1421,6 +2126,10 @@ namespace PrimMesher
|
||||||
newViewerFace.v2 = newLayer.coords[face.v2];
|
newViewerFace.v2 = newLayer.coords[face.v2];
|
||||||
newViewerFace.v3 = newLayer.coords[face.v3];
|
newViewerFace.v3 = newLayer.coords[face.v3];
|
||||||
|
|
||||||
|
newViewerFace.coordIndex1 = face.v1;
|
||||||
|
newViewerFace.coordIndex2 = face.v2;
|
||||||
|
newViewerFace.coordIndex3 = face.v3;
|
||||||
|
|
||||||
newViewerFace.n1 = faceNormal;
|
newViewerFace.n1 = faceNormal;
|
||||||
newViewerFace.n2 = faceNormal;
|
newViewerFace.n2 = faceNormal;
|
||||||
newViewerFace.n3 = faceNormal;
|
newViewerFace.n3 = faceNormal;
|
||||||
|
@ -1437,6 +2146,7 @@ namespace PrimMesher
|
||||||
// append this layer
|
// append this layer
|
||||||
|
|
||||||
int coordsLen = this.coords.Count;
|
int coordsLen = this.coords.Count;
|
||||||
|
int lastCoordsLen = coordsLen;
|
||||||
newLayer.AddValue2FaceVertexIndices(coordsLen);
|
newLayer.AddValue2FaceVertexIndices(coordsLen);
|
||||||
|
|
||||||
this.coords.AddRange(newLayer.coords);
|
this.coords.AddRange(newLayer.coords);
|
||||||
|
@ -1470,6 +2180,7 @@ namespace PrimMesher
|
||||||
iNext = startVert;
|
iNext = startVert;
|
||||||
|
|
||||||
int whichVert = i - startVert;
|
int whichVert = i - startVert;
|
||||||
|
//int whichVert2 = i - lastCoordsLen;
|
||||||
|
|
||||||
newFace.v1 = i;
|
newFace.v1 = i;
|
||||||
newFace.v2 = i - numVerts;
|
newFace.v2 = i - numVerts;
|
||||||
|
@ -1483,9 +2194,11 @@ namespace PrimMesher
|
||||||
if (this.viewerMode)
|
if (this.viewerMode)
|
||||||
{
|
{
|
||||||
// add the side faces to the list of viewerFaces here
|
// add the side faces to the list of viewerFaces here
|
||||||
int primFaceNum = 1;
|
//int primFaceNum = 1;
|
||||||
if (whichVert >= sides)
|
//if (whichVert >= sides)
|
||||||
primFaceNum = 2;
|
// primFaceNum = 2;
|
||||||
|
int primFaceNum = profile.faceNumbers[whichVert];
|
||||||
|
|
||||||
ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
|
ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
|
||||||
ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
|
ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
|
||||||
|
|
||||||
|
@ -1536,6 +2249,14 @@ namespace PrimMesher
|
||||||
newViewerFace2.v2 = this.coords[iNext - numVerts];
|
newViewerFace2.v2 = this.coords[iNext - numVerts];
|
||||||
newViewerFace2.v3 = this.coords[iNext];
|
newViewerFace2.v3 = this.coords[iNext];
|
||||||
|
|
||||||
|
newViewerFace1.coordIndex1 = i;
|
||||||
|
newViewerFace1.coordIndex2 = i - numVerts;
|
||||||
|
newViewerFace1.coordIndex3 = iNext - numVerts;
|
||||||
|
|
||||||
|
newViewerFace2.coordIndex1 = i;
|
||||||
|
newViewerFace2.coordIndex2 = iNext - numVerts;
|
||||||
|
newViewerFace2.coordIndex3 = iNext;
|
||||||
|
|
||||||
// profile cut faces
|
// profile cut faces
|
||||||
if (whichVert == cut1Vert)
|
if (whichVert == cut1Vert)
|
||||||
{
|
{
|
||||||
|
@ -1573,7 +2294,7 @@ namespace PrimMesher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert];
|
//newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert];
|
||||||
|
|
||||||
this.viewerFaces.Add(newViewerFace1);
|
this.viewerFaces.Add(newViewerFace1);
|
||||||
this.viewerFaces.Add(newViewerFace2);
|
this.viewerFaces.Add(newViewerFace2);
|
||||||
|
@ -1616,6 +2337,10 @@ namespace PrimMesher
|
||||||
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
|
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
|
||||||
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
|
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
|
||||||
|
|
||||||
|
newViewerFace.coordIndex1 = face.v1 - coordsLen;
|
||||||
|
newViewerFace.coordIndex2 = face.v2 - coordsLen;
|
||||||
|
newViewerFace.coordIndex3 = face.v3 - coordsLen;
|
||||||
|
|
||||||
newViewerFace.n1 = faceNormal;
|
newViewerFace.n1 = faceNormal;
|
||||||
newViewerFace.n2 = faceNormal;
|
newViewerFace.n2 = faceNormal;
|
||||||
newViewerFace.n3 = faceNormal;
|
newViewerFace.n3 = faceNormal;
|
||||||
|
@ -1630,6 +2355,7 @@ namespace PrimMesher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
|
/// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1826,6 +2552,10 @@ namespace PrimMesher
|
||||||
newViewerFace.v2 = newLayer.coords[face.v2];
|
newViewerFace.v2 = newLayer.coords[face.v2];
|
||||||
newViewerFace.v3 = newLayer.coords[face.v3];
|
newViewerFace.v3 = newLayer.coords[face.v3];
|
||||||
|
|
||||||
|
newViewerFace.coordIndex1 = face.v1;
|
||||||
|
newViewerFace.coordIndex2 = face.v2;
|
||||||
|
newViewerFace.coordIndex3 = face.v3;
|
||||||
|
|
||||||
newViewerFace.n1 = faceNormal;
|
newViewerFace.n1 = faceNormal;
|
||||||
newViewerFace.n2 = faceNormal;
|
newViewerFace.n2 = faceNormal;
|
||||||
newViewerFace.n3 = faceNormal;
|
newViewerFace.n3 = faceNormal;
|
||||||
|
@ -1886,9 +2616,13 @@ namespace PrimMesher
|
||||||
|
|
||||||
if (this.viewerMode)
|
if (this.viewerMode)
|
||||||
{
|
{
|
||||||
|
int primFaceNumber = profile.faceNumbers[whichVert];
|
||||||
|
if (!needEndFaces)
|
||||||
|
primFaceNumber -= 1;
|
||||||
|
|
||||||
// add the side faces to the list of viewerFaces here
|
// add the side faces to the list of viewerFaces here
|
||||||
ViewerFace newViewerFace1 = new ViewerFace();
|
ViewerFace newViewerFace1 = new ViewerFace(primFaceNumber);
|
||||||
ViewerFace newViewerFace2 = new ViewerFace();
|
ViewerFace newViewerFace2 = new ViewerFace(primFaceNumber);
|
||||||
float u1 = newLayer.us[whichVert];
|
float u1 = newLayer.us[whichVert];
|
||||||
float u2 = 1.0f;
|
float u2 = 1.0f;
|
||||||
if (whichVert < newLayer.us.Count - 1)
|
if (whichVert < newLayer.us.Count - 1)
|
||||||
|
@ -1936,6 +2670,14 @@ namespace PrimMesher
|
||||||
newViewerFace2.v2 = this.coords[iNext - numVerts];
|
newViewerFace2.v2 = this.coords[iNext - numVerts];
|
||||||
newViewerFace2.v3 = this.coords[iNext];
|
newViewerFace2.v3 = this.coords[iNext];
|
||||||
|
|
||||||
|
newViewerFace1.coordIndex1 = i;
|
||||||
|
newViewerFace1.coordIndex2 = i - numVerts;
|
||||||
|
newViewerFace1.coordIndex3 = iNext - numVerts;
|
||||||
|
|
||||||
|
newViewerFace2.coordIndex1 = i;
|
||||||
|
newViewerFace2.coordIndex2 = iNext - numVerts;
|
||||||
|
newViewerFace2.coordIndex3 = iNext;
|
||||||
|
|
||||||
// profile cut faces
|
// profile cut faces
|
||||||
if (whichVert == cut1Vert)
|
if (whichVert == cut1Vert)
|
||||||
{
|
{
|
||||||
|
@ -1987,7 +2729,7 @@ namespace PrimMesher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert];
|
//newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert];
|
||||||
this.viewerFaces.Add(newViewerFace1);
|
this.viewerFaces.Add(newViewerFace1);
|
||||||
this.viewerFaces.Add(newViewerFace2);
|
this.viewerFaces.Add(newViewerFace2);
|
||||||
|
|
||||||
|
@ -2002,7 +2744,7 @@ namespace PrimMesher
|
||||||
// calculate terms for next iteration
|
// calculate terms for next iteration
|
||||||
// calculate the angle for the next iteration of the loop
|
// calculate the angle for the next iteration of the loop
|
||||||
|
|
||||||
if (angle >= endAngle)
|
if (angle >= endAngle - 0.01)
|
||||||
done = true;
|
done = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2017,6 +2759,7 @@ namespace PrimMesher
|
||||||
// add the bottom faces to the viewerFaces list here
|
// add the bottom faces to the viewerFaces list here
|
||||||
Coord faceNormal = newLayer.faceNormal;
|
Coord faceNormal = newLayer.faceNormal;
|
||||||
ViewerFace newViewerFace = new ViewerFace();
|
ViewerFace newViewerFace = new ViewerFace();
|
||||||
|
//newViewerFace.primFaceNumber = newLayer.bottomFaceNumber + 1;
|
||||||
newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
|
newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
|
||||||
foreach (Face face in newLayer.faces)
|
foreach (Face face in newLayer.faces)
|
||||||
{
|
{
|
||||||
|
@ -2024,6 +2767,10 @@ namespace PrimMesher
|
||||||
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
|
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
|
||||||
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
|
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
|
||||||
|
|
||||||
|
newViewerFace.coordIndex1 = face.v1 - coordsLen;
|
||||||
|
newViewerFace.coordIndex2 = face.v2 - coordsLen;
|
||||||
|
newViewerFace.coordIndex3 = face.v3 - coordsLen;
|
||||||
|
|
||||||
newViewerFace.n1 = faceNormal;
|
newViewerFace.n1 = faceNormal;
|
||||||
newViewerFace.n2 = faceNormal;
|
newViewerFace.n2 = faceNormal;
|
||||||
newViewerFace.n3 = faceNormal;
|
newViewerFace.n3 = faceNormal;
|
||||||
|
@ -2206,9 +2953,17 @@ namespace PrimMesher
|
||||||
this.viewerFaces[i] = v;
|
this.viewerFaces[i] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if VERTEX_INDEXER
|
||||||
|
public VertexIndexer GetVertexIndexer()
|
||||||
|
{
|
||||||
|
if (this.viewerMode && this.viewerFaces.Count > 0)
|
||||||
|
return new VertexIndexer(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scales the mesh
|
/// Scales the mesh
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -436,9 +436,9 @@ namespace PrimMesher
|
||||||
{
|
{
|
||||||
Face face = this.faces[i];
|
Face face = this.faces[i];
|
||||||
Coord surfaceNormal = face.SurfaceNormal(this.coords);
|
Coord surfaceNormal = face.SurfaceNormal(this.coords);
|
||||||
this.normals[face.v1] += surfaceNormal;
|
this.normals[face.n1] += surfaceNormal;
|
||||||
this.normals[face.v2] += surfaceNormal;
|
this.normals[face.n2] += surfaceNormal;
|
||||||
this.normals[face.v3] += surfaceNormal;
|
this.normals[face.n3] += surfaceNormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numNormals = this.normals.Count;
|
int numNormals = this.normals.Count;
|
||||||
|
@ -462,6 +462,10 @@ namespace PrimMesher
|
||||||
vf.v2 = this.coords[face.v2];
|
vf.v2 = this.coords[face.v2];
|
||||||
vf.v3 = this.coords[face.v3];
|
vf.v3 = this.coords[face.v3];
|
||||||
|
|
||||||
|
vf.coordIndex1 = face.v1;
|
||||||
|
vf.coordIndex2 = face.v2;
|
||||||
|
vf.coordIndex3 = face.v3;
|
||||||
|
|
||||||
vf.n1 = this.normals[face.n1];
|
vf.n1 = this.normals[face.n1];
|
||||||
vf.n2 = this.normals[face.n2];
|
vf.n2 = this.normals[face.n2];
|
||||||
vf.n3 = this.normals[face.n3];
|
vf.n3 = this.normals[face.n3];
|
||||||
|
@ -520,6 +524,10 @@ namespace PrimMesher
|
||||||
for (i = 0; i < numVerts; i++)
|
for (i = 0; i < numVerts; i++)
|
||||||
this.coords[i] *= q;
|
this.coords[i] *= q;
|
||||||
|
|
||||||
|
int numNormals = this.normals.Count;
|
||||||
|
for (i = 0; i < numNormals; i++)
|
||||||
|
this.normals[i] *= q;
|
||||||
|
|
||||||
if (this.viewerFaces != null)
|
if (this.viewerFaces != null)
|
||||||
{
|
{
|
||||||
int numViewerFaces = this.viewerFaces.Count;
|
int numViewerFaces = this.viewerFaces.Count;
|
||||||
|
|
|
@ -805,7 +805,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// This sleeper is there to moderate how long it takes between
|
// This sleeper is there to moderate how long it takes between
|
||||||
// setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
|
// setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
|
||||||
|
|
||||||
Thread.Sleep(10);
|
//Thread.Sleep(10);
|
||||||
|
|
||||||
//Kill Body so that mesh can re-make the geom
|
//Kill Body so that mesh can re-make the geom
|
||||||
if (IsPhysical && Body != IntPtr.Zero)
|
if (IsPhysical && Body != IntPtr.Zero)
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
GridServices = "RemoteGridServicesConnector"
|
GridServices = "RemoteGridServicesConnector"
|
||||||
NeighbourServiceInConnector = true
|
NeighbourServiceInConnector = true
|
||||||
LandServiceInConnector = true
|
LandServiceInConnector = true
|
||||||
|
LLProxyLoginModule = true
|
||||||
|
|
||||||
[GridService]
|
[GridService]
|
||||||
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
|
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
NeighbourServiceInConnector = true
|
NeighbourServiceInConnector = true
|
||||||
LandServiceInConnector = true
|
LandServiceInConnector = true
|
||||||
HypergridServiceInConnector = true
|
HypergridServiceInConnector = true
|
||||||
|
LLProxyLoginModule = true
|
||||||
|
|
||||||
[AssetService]
|
[AssetService]
|
||||||
LocalGridAssetService = "OpenSim.Services.Connectors.dll:AssetServicesConnector"
|
LocalGridAssetService = "OpenSim.Services.Connectors.dll:AssetServicesConnector"
|
||||||
|
|
Loading…
Reference in New Issue