मुझे यकीन नहीं है कि आप किस भाषा में काम कर रहे हैं, लेकिन यहां स्थित यूनिटी 3 डी के लिए एक प्रक्रियात्मक जाल बाहर निकालना उदाहरण है:
http://unity3d.com/support/resources/example-projects/procedural-examples
मुझे यकीन है कि आप कोड को देख सकते हैं और इसे अपनी स्थिति के लिए फिर से काम कर सकते हैं।
संपादित करें: मैं एक ऐसे खेल पर काम कर रहा हूं जो एक प्रक्रियात्मक एक्सट्रूडेड रेल प्रणाली का उपयोग करता है जैसे आप शुरू कर रहे हैं लेकिन यह Un # 3 डी में C # में है। मैं आपको एक अवलोकन दूंगा कि कैसे मैं क्यूबिक बेज़ियर पथ के आधार पर अपने रेल एक्सट्रूज़न का निर्माण करता हूं, हालांकि रेल का जाल प्रक्रियात्मक रूप से उत्पन्न होता है, यह बेजियर पथ पर आधारित है जिसे मैं एक संपादक में समय से पहले परिभाषित करता हूं। यह आपके खेल के मामले में एक स्तर के संपादक की तरह होगा, मेरे मामले में, यह पिनबॉल टेबल डिजाइन कर रहा है। नीचे सूचीबद्ध एक उदाहरण है कि मैं यह कैसे कर रहा हूं:
1.) एक बेजियर पाथ क्लास का निर्माण / ढूँढें और उसे लागू करें। यह आपको अपने जाल बाहर निकालना के लिए स्रोत डेटा देगा। C # में एक है जिसे आप c ++ में पोर्ट कर सकते हैं।
http://forum.unity3d.com/threads/32954-Waypoints-and-constant-variable-speed-problems?p=213942
2.) एक बार जब आप एक बेज़ियर पथ बना लेते हैं, तो इस पथ के डेटा बिंदुओं का नमूना लिया जाता है। यह ऊपर दिए गए वर्ग पर इंटरप विधि के माध्यम से किया जा सकता है। यह आपको बेज़ियर पथ के साथ वेक्टर 3 बिंदुओं की एक सूची / सरणी देगा।
3.) स्टेप 2 से वेक्टर 3 बेज़ियर पथ डेटा को परिवर्तित करने के लिए एक हेल्पर क्लास बनाएं। इस मामले में, मेरे पास एक साधारण वर्ग है जिसे एक्सट्रूडेडट्रैलाइसेशन कहा जाता है जैसा कि नीचे परिभाषित किया गया है:
public class ExtrudedTrailSection
{
public Vector3 point;
public Matrix4x4 matrix;
public float time;
public ExtrudedTrailSection() { }
}
4.) अपने वेक्टर 3 नमूना डेटा के माध्यम से Iterate करें और इसे नमूना डेटा और एक आधार मैट्रिक्स के साथ आपूर्ति करने वाले ExtrudedTrailSections की एक सरणी में परिवर्तित करें जो आपके एक्सट्रूडेड मेष का मूल स्थान होगा।
- निम्नलिखित कोड का उपयोग करके अंतिम मैट्रिक्स 4x4 [] की एक सरणी बनाने के लिए ExtrudedTrailSections के सरणी का उपयोग करें:
Matrix4x4 worldToLocal = rootTransform.worldToLocalMatrix;
for (int i = 0; i < trailSections.Count; i++)
{
if (i == 0)
{
direction = trailSections[0].point - trailSections[1].point;
rotation = Quaternion.LookRotation(direction, Vector3.up);
previousRotation = rotation;
finalSections[i] = worldToLocal * Matrix4x4.TRS(position, rotation, Vector3.one);
}
// all elements get the direction by looking up the next section
else if (i != trailSections.Count - 1)
{
direction = trailSections[i].point - trailSections[i + 1].point;
rotation = Quaternion.LookRotation(direction, Vector3.up);
// When the angle of the rotation compared to the last segment is too high
// smooth the rotation a little bit. Optimally we would smooth the entire sections array.
if (Quaternion.Angle(previousRotation, rotation) > 20)
rotation = Quaternion.Slerp(previousRotation, rotation, 0.5f);
previousRotation = rotation;
finalSections[i] = worldToLocal * Matrix4x4.TRS(trailSections[i].point, rotation, Vector3.one);
}
// except the last one, which just copies the previous one
else
{
finalSections[i] = finalSections[i - 1];
}
}
6.) अब आपके पास Matrix4x4 का एक सरणी है [] और एक जाल को निकाल सकते हैं लेकिन पहले हमें इससे बाहर निकालने के लिए एक संदर्भ जाल की आवश्यकता है। मेरे पास एक उपयोगिता वर्ग है जो एक गोलाकार जाल चेहरा बनाएगा जो हम जाल बाहर निकालना विधि को आपूर्ति करेंगे।
public static List<Vector2> CreateCircle (double radius, int sides)
{
List<Vector2> vectors = new List<Vector2> ();
const float max = 2.0f * Mathf.PI;
float step = max / sides;
for (float theta = 0.0f; theta < max; theta += step) {
vectors.Add (new Vector2 ((float)(radius * Mathf.Cos (theta)), (float)(radius * Mathf.Sin (theta))));
}
return vectors;
}
7.) इस डेटा का केंद्र खोजें:
public static Vector2 CalculateCentroid(List<Vector2> vectorList)
{
//////////////////////////////////////////////////////////////////////////
// Local variables.
float fArea = 0.0f, fDistance = 0.0f;
Vector2 vCenter = Vector2.zero;
int nIndex = 0, nLastPointIndex = vectorList.Count - 1;
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Run through the list of positions.
for (int i = 0; i <= nLastPointIndex; ++i)
{
//////////////////////////////////////////////////////////////////////////
// Cacluate index.
nIndex = (i + 1) % (nLastPointIndex + 1);
// Calculate distance.
fDistance = vectorList[i].x * vectorList[nIndex].y - vectorList[nIndex].x * vectorList[i].y;
// Acculmate area.
fArea += fDistance;
// Move center positions based on positions and distance.
vCenter.x += (vectorList[i].x + vectorList[nIndex].x) * fDistance;
vCenter.y += (vectorList[i].y + vectorList[nIndex].y) * fDistance;
}
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Calculate the final center position.
fArea *= 0.5f;
vCenter.x *= 1.0f / (6.0f * fArea);
vCenter.y *= 1.0f / (6.0f * fArea);
//
//////////////////////////////////////////////////////////////////////////
return vCenter;
}
8.) अब जब हमारे पास एक रेडियल फेस मेष के लिए किनारे और केंद्र डेटा है, तो आप अपने डेटा का उपयोग करके एक मेष ऑब्जेक्ट का निर्माण कर सकते हैं। मेष में अंतिम शीर्ष केंद्र बिंदु है जिसकी हमने गणना की है। अंतिम जाल सिर्फ एक चेहरा है जो मेष एक्सट्रूज़न विधि को आपूर्ति किया जाता है जिसे मैंने एकता पैकेज के प्रोसीड्यूरल मेष एक्सट्रूज़न वर्ग में एक उदाहरण प्रदान किया है। फिर से, यह मेरी विधि है और जाहिर है कि आपको इस डेटा को ओपनजीएल में फीड करना होगा। यदि आपके पास एक 3 डी उपयोगिता पुस्तकालय है जिसे आप उपयोग कर रहे हैं या अपनी खुद की मेष कक्षा लिख सकते हैं, तो यह संभवतः आपके अंतिम extruded जाल को बनाने के लिए बेहतर काम करेगा क्योंकि इस डेटा को प्रतिपादन के लिए opengl द्वारा वास्तव में आवश्यक नहीं है। इस चेहरे की जाली का उपयोग सिर्फ मेष बाहर निकालना के लिए संदर्भ के रूप में किया जाता है।
List<Vector3> levelVerts = new List<Vector3>();
List<Vector2> levelUVBary = new List<Vector2>();
List<Vector2> levelUVs = new List<Vector2>();
List<int> levelTris = new List<int>();
int verticesPerNode = 4;
int edgeCount = sourceMeshData.Count;
List<Vector3> sourceVerts = new List<Vector3>();
//Debug.Log("smd.c:" + sourceMeshData.Count);
for (int i = 0; i < edgeCount; i++)
{
//Debug.Log("adding:"+levelShapeData[i].x+"/"+levelShapeData[i].y);
sourceVerts.Add(new Vector3(sourceMeshData[i].x, sourceMeshData[i].y, 0));
levelUVs.Add(new Vector2(0, 0));
//sourceVerts.Add(new Vector3(levelShapeData[i].x, levelShapeData[i].y, modelLength / 2f));
}
sourceVerts.Add(new Vector3(sourceMeshCenter.x, sourceMeshCenter.y, 0));
levelUVs.Add(new Vector2(0, 0));
for (int i = 0; i < edgeCount - 1; i++)
{ //0, 1, 2, 3
levelTris.Add(sourceVerts.Count - 1); //4, 4, 4, 4
levelTris.Add(i); //0, 1, 2,
levelTris.Add(i + 1); //1, 2, 3,
}
levelTris.Add(sourceVerts.Count - 1);
levelTris.Add(edgeCount - 1);
levelTris.Add(0);
9.) परिपत्र एक्सट्रूज़न विधि द्वारा आवश्यकतानुसार परिपत्र जाल के बाहरी किनारों का पता लगाएं। फिर से, इस कोड को एकता पैकेज में प्रदान किया गया है।
public class Edge
{
// The indiex to each vertex
public int[] vertexIndex = new int[2];
// The index into the face.
// (faceindex[0] == faceindex[1] means the edge connects to only one triangle)
public int[] faceIndex = new int[2];
}
public static Edge[] BuildManifoldEdges (Mesh mesh)
{
// Build a edge list for all unique edges in the mesh
Edge[] edges = BuildEdges(mesh.vertexCount, mesh.triangles);
// We only want edges that connect to a single triangle
ArrayList culledEdges = new ArrayList();
foreach (Edge edge in edges)
{
if (edge.faceIndex[0] == edge.faceIndex[1])
{
culledEdges.Add(edge);
}
}
return culledEdges.ToArray(typeof(Edge)) as Edge[];
}
10.) इस डेटा को मेष एक्सट्रूज़न विधि में फीड करें।
public static void ExtrudeMesh (Mesh srcMesh, Mesh extrudedMesh, Matrix4x4[] extrusion, Edge[] edges, bool invertFaces)
{
int extrudedVertexCount = edges.Length * 2 * extrusion.Length;
int triIndicesPerStep = edges.Length * 6;
int extrudedTriIndexCount = triIndicesPerStep * (extrusion.Length -1);
Vector3[] inputVertices = srcMesh.vertices;
Vector2[] inputUV = srcMesh.uv;
int[] inputTriangles = srcMesh.triangles;
//Debug.Log("inputUV:" + inputUV.Length);
Vector3[] vertices = new Vector3[extrudedVertexCount + srcMesh.vertexCount * 2];
Vector2[] uvs = new Vector2[vertices.Length];
int[] triangles = new int[extrudedTriIndexCount + inputTriangles.Length * 2];
// Build extruded vertices
int v = 0;
for (int i=0;i<extrusion.Length;i++)
{
Matrix4x4 matrix = extrusion[i];
float vcoord = (float)i / (extrusion.Length -1);
foreach (Edge e in edges)
{
//Debug.Log(e.vertexIndex.Length);
vertices[v+0] = matrix.MultiplyPoint(inputVertices[e.vertexIndex[0]]);
vertices[v+1] = matrix.MultiplyPoint(inputVertices[e.vertexIndex[1]]);
uvs[v+0] = new Vector2 (inputUV[e.vertexIndex[0]].x, vcoord);
uvs[v+1] = new Vector2 (inputUV[e.vertexIndex[1]].x, vcoord);
v += 2;
}
}
// Build cap vertices
// * The bottom mesh we scale along it's negative extrusion direction. This way extruding a half sphere results in a capsule.
for (int c=0;c<2;c++)
{
Matrix4x4 matrix = extrusion[c == 0 ? 0 : extrusion.Length-1];
int firstCapVertex = c == 0 ? extrudedVertexCount : extrudedVertexCount + inputVertices.Length;
for (int i=0;i<inputVertices.Length;i++)
{
vertices[firstCapVertex + i] = matrix.MultiplyPoint(inputVertices[i]);
uvs[firstCapVertex + i] = inputUV[i];
}
}
// Build extruded triangles
for (int i=0;i<extrusion.Length-1;i++)
{
int baseVertexIndex = (edges.Length * 2) * i;
int nextVertexIndex = (edges.Length * 2) * (i+1);
for (int e=0;e<edges.Length;e++)
{
int triIndex = i * triIndicesPerStep + e * 6;
triangles[triIndex + 0] = baseVertexIndex + e * 2;
triangles[triIndex + 1] = nextVertexIndex + e * 2;
triangles[triIndex + 2] = baseVertexIndex + e * 2 + 1;
triangles[triIndex + 3] = nextVertexIndex + e * 2;
triangles[triIndex + 4] = nextVertexIndex + e * 2 + 1;
triangles[triIndex + 5] = baseVertexIndex + e * 2 + 1;
}
}
// build cap triangles
int triCount = inputTriangles.Length / 3;
// Top
{
int firstCapVertex = extrudedVertexCount;
int firstCapTriIndex = extrudedTriIndexCount;
for (int i=0;i<triCount;i++)
{
triangles[i*3 + firstCapTriIndex + 0] = inputTriangles[i * 3 + 1] + firstCapVertex;
triangles[i*3 + firstCapTriIndex + 1] = inputTriangles[i * 3 + 2] + firstCapVertex;
triangles[i*3 + firstCapTriIndex + 2] = inputTriangles[i * 3 + 0] + firstCapVertex;
}
}
// Bottom
{
int firstCapVertex = extrudedVertexCount + inputVertices.Length;
int firstCapTriIndex = extrudedTriIndexCount + inputTriangles.Length;
for (int i=0;i<triCount;i++)
{
triangles[i*3 + firstCapTriIndex + 0] = inputTriangles[i * 3 + 0] + firstCapVertex;
triangles[i*3 + firstCapTriIndex + 1] = inputTriangles[i * 3 + 2] + firstCapVertex;
triangles[i*3 + firstCapTriIndex + 2] = inputTriangles[i * 3 + 1] + firstCapVertex;
}
}
if (invertFaces)
{
for (int i=0;i<triangles.Length/3;i++)
{
int temp = triangles[i*3 + 0];
triangles[i*3 + 0] = triangles[i*3 + 1];
triangles[i*3 + 1] = temp;
}
}
extrudedMesh.vertices = vertices;
extrudedMesh.uv = uvs;
extrudedMesh.triangles = triangles;
}
मेरे मामले में अंतिम आउटपुट इस तरह दिखता है ..
सौभाग्य, आपका खेल वास्तव में अच्छा लग रहा है! मुझे पता है अगर तुम यह पता लगाने?
चक