I couldnt help myself... I had to give it a try, I'm up to my eyeballs in directx anyway...


So you are back Benni! Cool, this IS your thread after all, and we've started
to drift off-track without you!

All we've done here is more of an entity 'splice' rather than a merge, I suppose.

OK then, try this one...

Its a stand-alone demo script of the ent_merge function Ive just completed today.
Just load the script in SED, save, and run. Look at the code itself afterwards.

Its just a timed demo, no interactions except camera zoom and angles.

It starts showing you the 'brick' entity it will build a wall from.
This is lightly tinted via the LIGHT flag so you can tell which one it is.

After a second, it will move to its next location with a bit of randomness
applied to its rotation and scales.

BUT ... BEFORE it moves, the script will run my "ent_merge" function, thereby
taking a 'copy' of the brick at that location and merging it into the "wall" entity.

Let it continue and it will create a wall of nine blocks before the cluster-beeps
indicate that the demo is complete...


Have fun and let me know what you think, and CERTAINLY let me know if it doesnt
work in certain situations! I havent tested it with that many models.

!! IMPORTANT !!
This function is CURRENTLY only able to store ONE skin. ie: the FIRST one it sees!
All consecutive merged models will use their own original UV's with that
first skin as the texture.
Fixing this is a major task that requires more research and I dont really have
the time to spare right know...

And listening to Benni, it may not even be necessary for HIS needs, anyway....


Enough of my PRATTLE ... it on with the show!

Click to reveal..
Code:
#include <acknex.h>
#include <default.c>
#include <d3d9.h>
//
#define PRAGMA_PATH "%EXE_DIR%\projects\shadertest"
//
//
//=========================================================================================
//=========================================================================================
//
// this declaration has been OMITTED from D3D9.H or some reason... but I need it...
//
HRESULT WINAPI D3DXConcatenateMeshes
(	LPD3DXMESH		*ppMeshes,
	UINT				NumMeshes, 
	DWORD				Options, 
	void*				junk1,
	void*				junk2,
	CONST D3DVERTEXELEMENT9	*pDecl, 
	LPDIRECT3DDEVICE9			pD3DDevice, 
	LPD3DXMESH		*ppMeshOut
);
//
//-----------------------------------------------------------------------------------------
//
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
 	//--------------------------------------------------------------------------------------
	// 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();  
			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							{	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);
 	//--------------------------------------------------------------------------------------
	return(targ);
}
//
//=========================================================================================
//=========================================================================================
//
//
//
//
void ent_randomize(ENTITY* ent)		//give entity a (limited) random angle and scale 
{	vec_set(ent.pan, vector(random(50)-25, random(50)-25, random(50)-25));
	vec_set(ent.scale_x, vector(random(1)+0.5, random(1)+0.5, random(1)+0.5));	}
//
//-----------------------------------------------------------------------------------------
//
//
//
function main()
{
 	video_switch(10,32,0);		level_load("");		wait(5);		diag("\n\n\n");
	vec_set(camera.x,vector(-750,0,10));				fps_min=fps_max=60;
 	def_move();		def_debug();		def_debug();
 	//--------------------------------------------------------------------------------------
	//
	// create an entity to 'assimilate' additional entities into itself
	ENTITY* wall = ent_create(CUBE_MDL, nullvector, NULL);	ent_clone(wall);
	//
	ent_merge(wall, wall);		//initialize WALL entity to an 'empty' mesh
	//
	// create 'another brick in the wall'	and color it differently so it stands out
	ENTITY* brick = ent_create("box.mdl", nullvector, NULL);
	vec_set(brick.blue, vector(50,50,50));		set(brick, LIGHT);
	wait(-1);	beep();
	//
	//
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.z += 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.y += 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.z -= 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.z -= 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.y -= 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.y -= 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.z += 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then move it to the next location, and pause
	ent_merge(wall, brick);		brick.z += 200;	ent_randomize(brick);
	wait(-1);	beep();
	//
	// merge the brick into the wall, and then remove the brick cause we are all finished
	ent_merge(wall, brick);		ent_remove(brick);	
	beep();	beep();	beep();	beep();	
	//
}




"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial