Also, erst rufst du für einen Vertex ent_getvertex auf, ist ja klar, also wie im Beispiel z.B. mit
CONTACT* contact = ent_getvertex(my, NULL, 123);
für den Vertex mit der Nummer 123 aus dem my-Modell. Das struct ist in atypes.h aufgeführt, wird aber auch in Teilen in der Manual abgedruckt. Hier das ganze Struct:
typedef struct CONTACT {
D3DVERTEX *v; // contact position in entity coordinates
var x,y,z; // contact point in world coordinates
var nx,ny,nz; // contact normal in world coordinates
var u1,v1; // hit position on lightmap
var u2,v2;
var vertex; // closest vertex number
var triangle; // triangle number
var chunk; // mesh number
void* model; // internal mesh info
var light;
var alpha;
var blue,green,red; // lightmap values at hit position
long flags; // hit flags
ENTITY* entity; // hit entity, or NULL for level geometry
BMAP *skin1,*skin2,*skin3,*skin4; // hit textures
char* texname; // hit texture name
var subset; // mesh group
} CONTACT;
Die Kommentare geben ja schon sehr viel Auskunft darüber, was da drin gespeichert ist. Interessant für dich ist jetzt das v-Feld.
Im v-Feld ist ein D3DVERTEX*-Pointer gespeichert, indem die relativen Daten (Position, Normale, usw.) vom ausgewählten Vertex drin stehen. Wenn du in dem Feld die Werte veränderst und das dann wieder mit ent_setvertex benutzt, aktualisierst du das Mesh! D3DVERTEX ist auch ein struct und ebenfalls in der atypes.h wie folgt definiert:
typedef struct {
float x,y,z; // position in DirectX coordinates
float nx,ny,nz; // normal
float u1,v1; // first coordinate set, for textures
float u2,v2; // second coordinate set, for shadow maps
float x3,y3,z3,w3; // third coordinate set, for tangent vector and handedness
float tu4,tv4; // 4th coordinate set, for additional data
} D3DVERTEX;
Du musst jetzt also theoretisch den z-Wert kippen. Da aber in DirectX die Y/Z-Achsen vertauscht sind, musst du das mit der Y-Koordinate machen, also z.B. so:
Wenn du das mit allen Vertices machst, spiegelst du das Mesh gegen die (Acknex) XY-Ebene. Dann sind aber alle Normalen falsch rum, deshalb musst du die umdrehen. Die Normale eines Vertex steht in n = (nx, ny, nz) des D3DVERTEX structs. Du kannst einfach den Vector mit -1 skalieren, dann ist die Normale umgedreht. Das geht dann z.B. so:
VECTOR n;
vec_set(&n, vector(contact->v->nx, contact->v->ny, contact->v->nz));
vec_scale(&n, -1);
contact->v->nx = n.x;
contact->v->ny = n.y;
contact->v->nz = n.z;
Dann musst du nur noch mit ent_setvertex das (modifizierte) Contact-Struct in den Vertex des Meshes übertragen. Wenn du z.B. ein Modell namens "enemy.mdl" hast und das für eine Entity machst, dann wirst du merken, dass jetzt -alle- Entities, die von der Datei "enemy.mdl" geladen sind, gespiegelt sind. Das liegt daran, dass Gamestudio ressourcensparend ist und das Mesh für die Datei nur EINMAL lädt und nicht für jede Entity separat. Wenn du jetzt also im Spiel eine gespiegelte Entity haben willst, musst du die Meshdaten vorher kopieren, das geht mit ent_clone.
Wenn du nur wenige Entities hast, würde ich dann einfach mit clone und der oben beschriebenen Prozedur arbeiten.
Wenn du allerdings unbeschränkt viele Entities so benutzt, dann wäre es am schlausten dir irgendwo einen Zeiger auf eine gespiegelte Entity zu merken und dann das mesh für neue Entities wieder zu benutzen. Allerdings habe ich das noch nicht gemacht und weiß nicht genau ob das so geht, aber ich denke, dass du dir dann mit ent_buffers das gespiegelte Mesh holen kannst und für die neue Entity setzen kannst. Dann hast du immer zwei Meshes im Speicher, einmal das "normale" und einmal das "gespiegelte". Das wäre dann am ressourcensparendsten.