ent_getvertex(ENTITY* ent, CONTACT* c, var num);
ent_setvertex(ENTITY* ent, CONTACT* c, var num);
Liefert einen einzelnen Vertex eines Modell- oder Terrain-Meshs zurück oder setzt diesen. Die Funktionen lassen sich zum Umformen des Mesh in Echtzeit verwenden.
Parameter:
ent |
Modell- oder Terrain-Entity-Pointer. |
num |
Vertex-Nummer, die mit 1 beginnt. |
c |
Pointer auf einv orgefülltes CONTACT*-Strukt (definiert in atypes.h) zum Setzen oder Lesen des Vertex-Inhalts. Mit ent_getvertex kann NULL zur Rückgabe des Pointers an ein internes, statisches CONTACT-Struk.
|
Die folgenden Elemente des CONTACT-Structs werden verwendet (s. auch hit):
c.v |
D3DVERTEX* -Pointer der gegenwärtig animierten und interpolierten Mesh-Position, die von ent_getvertex gesetzt ist und von ent_setvertex zu Updaten der Mesh benutzt wird. Beachten Sie, dass die Vertex-Position float ist anstelle von var und das DX-Koordinatensystem benutzt. Das Format D3DVERTEX wird unter shader section beschrieben und ist in atypes.h. definiert.
|
c.x,y,z |
VECTOR, der die Vertexposition in lokalen Entity-Koordinaten enthält, wird von ent_getvertex gesetzt. Bei nicht-animierten Entities ist die Position dieselbe wie in c.v. Bei Vertex-animierten Entities ist es die Vertex-Position im gegenwärtigen nicht-interpolierten Frame. Bei Bones-animierten Entities ist es die Vertex-Position des Grundframes. Setzen Sie c.v auf NULL wenn ent_setvertex anstatt c.v diesen Vertex updaten soll. Das Updaten von c.v ist etwas schneller, funktioniert aber nicht fü animierte Entities.
|
c.nx,ny,nz |
VECTOR , der die von ent_getvertex gesetzte Vertexnormale enthält. |
c.vertex |
Lokale Vertexnummer innerhalb der Untermesh. Wird von ent_getvertex gesetzt und benutzt ent_setvertex für Multimesh-Entities. |
c.chunk |
Unter-Meshnummer im Falle von Multimesh-Entities wie Map-Entities oder parzelliertes Terrain. Wird von ent_getvertex gesetzt und von ent_setvertex benutzt. |
c.model |
Unter-Meshpointer, wird von ent_getvertex gesetzt. Ist dieser Pointer ungleich Null, verwendet ent_getvertex anstelle des num-Parametersden c.vertex-Wert dür die Vertexnujmmer. Dies beschleundigt die Funktion bei Multi-Mesh-Entities. Wenn ent_getvertex nicht vor ent_setvertex aufgerufen wurde, setzen Sie diesen Pointer auf NULL. |
Rückgabewerte:
CONTACT* Strukt-Pointer, oder NULL wenn die Funktion fehlschlägt.
Speed:
Langsam beim ersten Aufruf, schnell bei nachfolgenden Aufrufen.
Bemerkungen:
- Das Modifizieren eines Mesh einer bestimmten Entity betrifft sämtliche Entities, die dasselbe Mesh verwenden. Um dies zu verhindern, benutzen Sie ent_clone.
- Das Updaten gemeinsam benutzter Vertices von Terrainparzellen, Meshnähten oder LOD-Meshes sowie das Updaten der sichtbaren Bounding-Box und der Kollisionshülle wird von ent_setvertex am Ende des Framezyklus´automatisch gehandhabt. Daher wird die neue Meshgröße nach dem Modifizieren einer Mesh von Funktionen wie c_setminmax, vec_for_min und vec_for_max einen Framezyklus später wiedergespiegelt. Die Kollisions-Bounding-Box bleibt unverändert. Falls gewünscht, kann min_x .. max_x danach manuell verändert werden.
- A7.76 Das Updaten der Kollisionshülle eines großen Terrains kann lange dauern. Um dem vorübergehend aus dem Weg zu gehen, setzen Sie das Flag PASSABLE des Terrains und setzen es im selben Framezyklus wieder zurück sobald die Terrainverformung fertig ist.
- Vertexmanipulation bei parzelliertem Terrain unterstützt nur quadratische Parzellen. Aus diesem Grund müssen die Größen von x und y von parzelliertem Terrain ein Vielfaches der Parzellengröße sein (terrain_chunk) - andernfalls bekommt das Terrain an seinen Grenzen nicht-quadratische abgeschnittene Parzellen an seinen Grenzen. Für die voreingestellte Parzellengröße von 32 Meshquadraten sind die Beispiele für gültige Terraingrößen 64x64, 160x160, 320x320 Quadrate bzw. 65x65, 161x161, oder 321x321 Vertices.
- Der c.v-Pointer zeigt in den Mesh-Vertexbuffer, welcher ein Array der D3DVERTEX-Strukte ist und eine von nt_status(ent,1)*ent_status(ent,22) gegebene Gesamtgröße hat. Das Aufrufen von ent_getvertex(ent,NULL,1) gefolgt von ent_setvertex(ent,c,1) liefert einen Pointer auf den Start des Vertexbuffers zurück und ermöglicht ein Verändern des gesamten Vertexbuffers ohne weiteres Aufrufen von ent_getvertex oder ent_setvertex. Allerdings betrifft diese schnelle Methode nur eine Meshparzelle von Multimesh-Entities und die die Reihenfolge der Zeilen oder Spalten der Vertices im Buffer entsprechen in diesem Fall der Parzellengröße und nicht der Größe des gesamten Terrains.
- Bei Levelgeometrie und parzelliertem Terrain sind die Entity-Koordinaten (c.x,y,z vecor) dieselben wie die Weltkoordinaten.
!! Bei En tity-Meshes und nicht-parzelliertem Terrain, sind die Entitykoordinaten lokale Koordinaten ohne Position und Skalierung. Lokale Koordinaten lassen sich per vec_for_ent / vec_to_ent von oder in Weltkoordinaten umwandeln und Normale können mit vec_rotate umgewandelt werden.
- In Terrain-Meshes sind Vertices in einer Reihen- und Spaltenreihenfolge sortiert. In irregulären Meshes sind die Vertices nach ihren Nummern, die in MEDs Statuszeile angezeigt werden, sortiert. Zuerst die Originalvertices mit eindeutigen xyz-Positionen und dann die duplizierten Vertices mit denselben xyz-Positionen aber anderen uv-Werten.
- Diese Funktionen ersetzen vec_for_mesh und vec_to_mesh, die Multimesh-Objekte nicht unterstützt haben.
Version
A7.62 LC
Beispiele (lite-C):
// raise all terrain vertices by 5 units
function raise_terrain(ENTITY* terrain)
{
int i = ent_status(terrain,0); // number of vertices
for (; i>0; i--) {
CONTACT* c = ent_getvertex(terrain,NULL,i);
c.v.y += 5.0; // raise the vertex (y is the height in DX coorcinates)
ent_setvertex(terrain,c,i);
}
}
// use a gun to produce mole-hills in terrain
function mole_gun()
{
while (1)
{
// calculate the target vector
VECTOR trace_target;
vec_set(trace_target,vector(5000,0,0)); // firing range 5000 quants
vec_rotate(trace_target, camera.pan);
vec_add(trace_target, camera.x);
// display a red spot at the target position
if (c_trace(camera.x,trace_target, IGNORE_PASSABLE | USE_POLYGON| SCAN_TEXTURE) > 0) // hit something?
draw_point3d(hit.x,vector(50,50,255),100,3);
if (key_ctrl && HIT_TARGET && you && ent_type(you) == 4) // fire onto terrain
{
// create a mole-hill by elevating the closest terrain vertex
var vertex_num = ent_nextvertex(you,hit.x);
CONTACT* contact = ent_getvertex(you,NULL,vertex_num);
c.z += 10; // increase the vertex height
c.v = NULL; // c.x,y,z was changed, instead of c.v
ent_setvertex(you,c,vertex_num); // update the mesh
wait(-0.5); // reload
}
wait(1);
}
}
Siehe auch:
ent_status, ent_nextvertex, ent_getmesh, ent_buffers, hit
► Aktuelle Version Online