ENTITY* ent_merge(ENTITY* targ, ENTITY* src)
{ // verify that pointer parameters are valid... otherwise abort.
if(targ==NULL) { return(NULL); } //invalid TARGET entity pointer
if(src ==NULL) { return(NULL); } //invalid SOURCE entity pointer
var old_coll_mode=collision_mode; collision_mode=1;
//--------------------------------------------------------------------------------------
// initialize TARGET entity to a brand new 'empty' mesh
LPD3DXMESH meshes[3]; (meshes[0])=(meshes[1])=(meshes[2])=NULL;
short *tbuff; D3DVERTEX *vbuff;
if(targ==src)
{ D3DXCreateMesh(0x01,0x03,D3DXMESH_MANAGED,pvertexdecl,pd3ddev,&meshes[1]);
(meshes[1])->LockIndexBuffer (0, (void**)&tbuff);
tbuff[0]=0; tbuff[1]=1; tbuff[2]=2; (meshes[1])->UnlockIndexBuffer();
if((meshes[1])!=NULL) if(((meshes[0])=ent_getmesh(targ,0,0)))
{ ent_setmesh(targ,(meshes[1]),0,0); //(meshes[0])->Release();
collision_mode=old_coll_mode; return(targ); } }
//--------------------------------------------------------------------------------------
// merge supplied meshes into a new single mesh, and re-assign/release accordingly
meshes[0]=ent_getmesh(targ,0,0); meshes[1]=ent_getmesh(src,0,0);
D3DXConcatenateMeshes(meshes,0x2,D3DXMESH_MANAGED,0,0,pvertexdecl,pd3ddev,&meshes[2]);
int t,v, vert_off=ent_status(targ,1), vert_end=vert_off+ent_status(src,1);
//if((meshes[0])!=NULL) { (meshes[0])->Release(); }
if((meshes[2])!=NULL) { ent_setmesh(targ,(meshes[2]),0,0); }
else { collision_mode=old_coll_mode; return(NULL); }
if(!ent_status(targ,8)) { ent_setskin(targ,ent_getskin(src,1),1); } //if need skin
//--------------------------------------------------------------------------------------
// transform merged-in vertices
VECTOR tmpV; D3DVERTEX* vb; long* ab; ent_buffers(targ, 0,0, &vb, 0,&ab);
for(v=vert_off; v<vert_end; v++)
{ vb[v].nx = vb[v].ny = vb[v].nz = 0;
vec_mul(vec_set(tmpV, vector(vb[v].x,vb[v].z,vb[v].y)), src.scale_x);
vec_sub(vec_add(vec_rotate(tmpV, src.pan), src.x), targ.x);
vb[v].x=tmpV.x; vb[v].y=tmpV.z; vb[v].z=tmpV.y; }
for(t=0; t<ent_status(targ,4); t++) { ab[t] = NULL; }
//--------------------------------------------------------------------------------------
// re-calculate all normals
DWORD* p_adjacency = sys_malloc(ent_status(targ,4)*3*sizeof(DWORD));
(meshes[2])->GenerateAdjacency(0.001, p_adjacency);
D3DXComputeNormals((meshes[2]), p_adjacency); sys_free(p_adjacency);
(meshes[2])->OptimizeInplace(0x03000000, p_adjacency, NULL, NULL, NULL);
//--------------------------------------------------------------------------------------
collision_mode=old_coll_mode; return(targ);
}