Moje programové kódy pre LineFace a MeshFace snapping:
(GIT, LineFace: https://github.com/indicatrix-git/tycoon-terrain-enhanced/blob/main/SnapLineFace.cs)
(GIT, MeshFace: https://github.com/indicatrix-git/tycoon-terrain-enhanced/blob/main/SnapMeshFace.cs)
public Vector3 SnapLineFace(Vector3 hitPoint)
{
float[] Xaxis = new float[4];
float[] Yaxis = new float[4];
float[] Zaxis = new float[4];
int xx = (int)hitPoint.x; float x = hitPoint.x - xx;
int zz = (int)hitPoint.z; float z = hitPoint.z - zz;
if (x >= 0.0f && x <= 1.0f)
{
Xaxis[0] = xx;
Xaxis[1] = xx;
Xaxis[2] = xx + 1;
Xaxis[3] = xx + 1;
}
if (z >= 0.0f && z <= 1.0f)
{
Zaxis[0] = zz;
Zaxis[1] = zz + 1;
Zaxis[2] = zz + 1;
Zaxis[3] = zz;
}
Yaxis[0] = FunctionalValueY(Xaxis[0], Zaxis[0]);
Yaxis[1] = FunctionalValueY(Xaxis[1], Zaxis[1]);
Yaxis[2] = FunctionalValueY(Xaxis[2], Zaxis[2]);
Yaxis[3] = FunctionalValueY(Xaxis[3], Zaxis[3]);
lineRenderer01.SetPosition(0, new Vector3(Xaxis[0], Yaxis[0], Zaxis[0]));
lineRenderer01.SetPosition(1, new Vector3(Xaxis[1], Yaxis[1], Zaxis[1]));
lineRenderer02.SetPosition(0, new Vector3(Xaxis[1], Yaxis[1], Zaxis[1]));
lineRenderer02.SetPosition(1, new Vector3(Xaxis[2], Yaxis[2], Zaxis[2]));
lineRenderer03.SetPosition(0, new Vector3(Xaxis[2], Yaxis[2], Zaxis[2]));
lineRenderer03.SetPosition(1, new Vector3(Xaxis[3], Yaxis[3], Zaxis[3]));
lineRenderer04.SetPosition(0, new Vector3(Xaxis[0], Yaxis[0], Zaxis[0]));
lineRenderer04.SetPosition(1, new Vector3(Xaxis[3], Yaxis[3], Zaxis[3]));
return GetCenterFace(hitPoint);
}
public Vector3 SnapMeshFace(Vector3 hitPoint)
{
Vector3[] verticesFace;
Vector3[] normalsFace;
Vector2[] uvFace;
int[] trianglesFace;
float[] Xaxis = new float[4];
float[] Yaxis = new float[4];
float[] Zaxis = new float[4];
int xx = (int)hitPoint.x; float x = hitPoint.x - xx;
int zz = (int)hitPoint.z; float z = hitPoint.z - zz;
float dy = 0.01f;
if (x >= 0.0f && x <= 1.0f)
{
Xaxis[0] = xx;
Xaxis[1] = xx;
Xaxis[2] = xx + 1;
Xaxis[3] = xx + 1;
}
if (z >= 0.0f && z <= 1.0f)
{
Zaxis[0] = zz;
Zaxis[1] = zz + 1;
Zaxis[2] = zz + 1;
Zaxis[3] = zz;
}
Yaxis[0] = FunctionalValueY(Xaxis[0], Zaxis[0]);
Yaxis[1] = FunctionalValueY(Xaxis[1], Zaxis[1]);
Yaxis[2] = FunctionalValueY(Xaxis[2], Zaxis[2]);
Yaxis[3] = FunctionalValueY(Xaxis[3], Zaxis[3]);
verticesFace = new Vector3[]
{
new Vector3(Xaxis[0], Yaxis[0] + dy, Zaxis[0]),
new Vector3(Xaxis[1], Yaxis[1] + dy, Zaxis[1]),
new Vector3(Xaxis[2], Yaxis[2] + dy, Zaxis[2]),
new Vector3(Xaxis[3], Yaxis[3] + dy, Zaxis[3])
};
trianglesFace = new int[]
{
0, 1, 2,
2, 3, 0
};
normalsFace = new Vector3[]
{
-Vector3.forward,
-Vector3.forward,
-Vector3.forward,
-Vector3.forward
};
uvFace = new Vector2[]
{
new Vector2(Xaxis[0], Zaxis[0]),
new Vector2(Xaxis[1], Zaxis[1]),
new Vector2(Xaxis[2], Zaxis[2]),
new Vector2(Xaxis[3], Zaxis[3])
};
meshFace.Clear();
meshFace.vertices = verticesFace;
meshFace.triangles = trianglesFace;
meshFace.normals = normalsFace;
meshFace.uv = uvFace;
meshFace.RecalculateNormals();
return GetCenterFace(hitPoint);
}
Uvedený kód je platný pre tzv. LineFace a tzv. MeshFace. Je to analogické, v prvom prípade máme Face pozostávajúci z 4 úsečiek a v druhom prípade máme Face pozostávajúci z Mesh-u. Mesh je pojem z počítačovej grafiky, ktorý označuje plochu, ktorá môže mať definovanú farbu alebo aj textúru (obrázok). V prípade LineFace je to z kódu pochopiteľné v zmysle toho, že teda nájdeme 4 vertexy a tieto 4 vertexy priradíme jednotlivým úsečkám. V prípade MeshFace je to analogické, kde vytvoríme bázicky vertices a indices (triangleFace) a dodatočne aj UV mapy a normálu. Rovnako pre 4 vertexy v rámci tvorby Mesh plôšky, priradíme jednotlivé súradnice týmto vertexom. Pre indices maticu už len priradíme priradené 4 vertexy v smere hodinových ručičiek v niektorej z 3 konštelácií podľa definície tvorby Mesh plôšky.
Pri VerticesFace figuruje malý prírastok dy pre y súradnicu (y = 0.01). Je to z toho dôvodu, aby bolo vidieť samotný Face. Ak by tam tento prírastok nebol, tak úroveň plôšky, Face by bola na rovnakej úrovni ako úroveň samotných vertexov pre terén, ktorý obsahuje tiež textúru. Viditeľnosť dvoch Mesh objektov s textúrou s rovnakými súradnicami znemožňuje viditeľnosť jedného z nich, resp. v limitnom prípade by figurovala Mesh plôška pod úrovňou terénu a teda toto je najpravdepodobnejší dôvod toho, že sa samotná Face plôška nezobrazí na teréne, ale tesne pod ňou. Z toho dôvodu som zadal prírastok dy na y súradnicu.
Pridávam ešte kód pre získanie funkčnej hodnoty zo súradníc x a z:
float FunctionalValueY(float snapX, float snapZ)
{
float snapY = 0;
for (int Ci = 0, Cz = 0; Cz <= TerrainManager.instance.terrainWidth; Cz++)
{
for (int Cx = 0; Cx <= TerrainManager.instance.terrainWidth; Cx++, Ci++)
{
if (TerrainManager.instance.coords[Ci].x == snapX &&
TerrainManager.instance.coords[Ci].z == snapZ)
{
snapY = TerrainManager.instance.coords[Ci].y;
}
}
}
return snapY;
}
Napísal som to úplne intuitívne, tak jednoducho. Samozrejme, je možné to napísať sofistikovanejšie, ale minimálne v prvej verzii môjho kódu to nechávam zatiaľ v takejto základnej forme a možno to už bude aj konečná forma.
V nasledujúcom videu to popisujem podrobnejšie:
0 comments:
Post a Comment