Also, erst rufst du für einen Vertex ent_getvertex auf, ist ja klar, also wie im Beispiel z.B. mit

Code:
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:

Code:
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:

Code:
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:

Code:
contact->v->y *= -1;



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:

Code:
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.

Last edited by HeelX; 10/22/12 10:41.