Merge 2 Meshes/Entities during game...

Posted By: Benni003

Merge 2 Meshes/Entities during game... - 05/05/12 07:22

Hello, I need to merge 2 Entities during game..
I think it should be possible to take the meshpointer of the one entity, take the meshpointer of the other and join them. Then I could set this new mesh to one of the entities. Both have the same skin. Then I also need to merge vertexes which habe the same positions. This is my theory, but in practice my experience in mesh manipulation is not good.
I think d3d9.h have some useful commands.
How can I code it? I would be so thankful for help!
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 05/05/12 19:16

look into ent_buffers , ent_vertices.
ent_buffers wil give you access to the

triangles buffers (indices into vertices array ,3 vertices forms a triangle)
and the vertices buffers (an array of vectors-positions of vertices)

it will also return the amount of triangles in the triangle buffer
and ent_vertices if its a model will return you the amount of vertices

so you could also use ent_getmesh and ent_setmesh which deals with d3dmesh/buffers of your target meshes

if they are animated im not sure how that would be handled ,maby a parent and
child relationship (in model terms)

i guess theres more than one way to handle it(merging them)
depending on your situation but a start would be to look into those functions
theres also ent_status which would give you valuable information if you
need it..

if perhaps you could be more specific in details as to what you want
to achieve apart from merging meshes ,like are they animated or not etc etc
Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 05/05/12 19:27

Hello Wjbender, thanks for your answer. The Entities are not animated. I need it for a kind of wallcreation. I could also use many of entities, but this would damage the framerate, because the peaces are very small and there would be many entities needed. That's why I want to Merge meshes. In this point I would be grateful for some codeexamples, because I never programmed in meshmanipulation like this.
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 05/06/12 09:51

i will see when i have time if i could perhaps code a function to help
you with this and then post the code up here if i succeed
Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 05/06/12 11:41

Ok, I'm waiting for learning from you wink
Posted By: sivan

Re: Merge 2 Meshes/Entities during game... - 05/06/12 17:03

I would need this too. EvilSOB put up a code to the forum some days or a week ago how to create a skinned d3d mesh and make an entity from it. it might be useful. (I had no time to really dig into it)
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 05/07/12 09:36

this is as far as i can help you out

demo

note : this demo does not take entity rotation into account it uses
the rotation of the models file, and i dont know if the uv's are correct
i didnt test on textured models and also you will have to do the materials
i think but anyway i cant help any further than this...
Oh yes i forgot you have to take position in concideration
and offset vertices positions acordingly same for scale
if i am not mistaken

Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 05/07/12 11:13

Thank you Wjbender for your help! Yes the Entities are merged! Now I will look into every line of code and try to understand.
Hope I can manage it with material and texture..
laugh
Posted By: sivan

Re: Merge 2 Meshes/Entities during game... - 05/07/12 12:06

in A7 I get an error message because of "pvertexdecl", it is said to be undeclared in the line of "D3DXCreateMesh(merged_triangles,merged_vertices,D3DXMESH_MANAGED,pvertexdecl,pd3ddev,&mesh1);"
but some dx things differs in A7 and A8, I can check by A8 only at home.
Posted By: Ch40zzC0d3r

Re: Merge 2 Meshes/Entities during game... - 05/07/12 14:27

I think MasterQ32 made soemthign similar. Just ask him laugh
Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 05/10/12 06:57

Thanks, I wrote MasterQ32, but I still haven't an answer yet. We will see wink
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 05/28/12 21:07

@Wjbender, thank you for this great contribution!

I post this late answer, because I was worrying about that the merging wasn't perfect, there are some triangles off.

I don't get that solved.
I would be happy, if anybody offers an advice how to solve this! laugh
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 05/30/12 19:40

Hi. I have not tested this much myself .it was more of a proof pf concept
written in an understandable manner for the poster of this thread . I could
look into it a bit further and see if perhaps i may be of help to you, provided
that you go into a bit more detail so that i may try and see what you see
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 05/30/12 22:32

Okay, after another bunch of tests I nailed it down to the relation between vertices of the model and the vertices needed for its skin.
When their numbers are identical, then everything is fine.
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 05/31/12 15:58

Got it!

You need the number of vertices including the vertices that are duplicated due to the skin uvs.

Replace:
int vertices1=ent_vertices(source1);
int vertices2=ent_vertices(source2);

with
int vertices1=ent_status(source1,1);
int vertices2=ent_status(source2,1);

Now, I hope to find a way to include the position, scale and rotation of the models.
Last point is to use the different skins as well.
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 05/31/12 16:48

Okay now i understand ,yes the rest of the function was poorly written
i was wondering how to achieve orientation and position and scale and skins
perhaps getmesh would return buffer with all that rotation positiom scale?
I havent tried it yet .position and scale shouldnt be to hard its the rotation
that bothers me im not very good with vectors and matrices. It would be
Great if you are able to solve the function
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 05/31/12 17:18

Maybe, one has to start with setting a center of the new model, and after that measure the vertex positions in relation to that center point.

Relaating the skin, I'm planing to sew the skins into one bitmap, and shift the vs depending the position of the models skin within the new bitmap.

Anyway, thank you very much for your base work, without it I wouldn't have any start at all.
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 05/31/12 17:54

That sounds great best of luck . Heres some form of code i have used
before
x=meshpos.x+vertex.x*scale.x
same for y and z
x being the new vertex position and scale taken from the source models position,vertex,scale
rotation i have no idea .
Anyway sure you wil solve it better and if you do could i ask for help
with rotating vertices as i need it for my navmesh project?
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 05/31/12 21:13

As soon as I know a solution, I share it!
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 05/31/12 22:14

I got the rotation working.
It is vec_rotate, inserted with VECTOR temp1; and the switch from y and z in the following way:

Code:
for (iterate=0;iterate<vertices1;iterate++)	
		{
			temp1.x=vertex_buffer1[iterate].x;
			temp1.y=vertex_buffer1[iterate].z;
			temp1.z=vertex_buffer1[iterate].y;
			vec_rotate(temp1.x, source1.pan);
			
			merged_vertex_buffer[iterate].x=temp1.x;
			merged_vertex_buffer[iterate].y=temp1.z;
			merged_vertex_buffer[iterate].z=temp1.y;
			
			merged_vertex_buffer[iterate].u1=vertex_buffer1[iterate].u1;
			merged_vertex_buffer[iterate].v1=vertex_buffer1[iterate].v1;
			merged_vertex_buffer[iterate].u2=vertex_buffer1[iterate].u2;
			merged_vertex_buffer[iterate].v2=vertex_buffer1[iterate].v2;
			
		}
		
		offsetv+=vertices1;
		
		for (iterate=0;iterate<vertices2;iterate++)	
		{
			temp1.x=vertex_buffer1[iterate].x;
			temp1.y=vertex_buffer1[iterate].z;
			temp1.z=vertex_buffer1[iterate].y;
			vec_rotate(temp1.x, source2.pan);
			
			merged_vertex_buffer[iterate+offsetv].x=temp1.x;
			merged_vertex_buffer[iterate+offsetv].y=temp1.z;
			merged_vertex_buffer[iterate+offsetv].z=temp1.y;
			
			merged_vertex_buffer[iterate+offsetv].u1=vertex_buffer2[iterate].u1;
			merged_vertex_buffer[iterate+offsetv].v1=vertex_buffer2[iterate].v1;
			merged_vertex_buffer[iterate+offsetv].u2=vertex_buffer2[iterate].u2;
			merged_vertex_buffer[iterate+offsetv].v2=vertex_buffer2[iterate].v2;
			
		}


Posted By: MasterQ32

Re: Merge 2 Meshes/Entities during game... - 06/01/12 00:14

sorry for holding back, but my system wasn't showable before
Sorry but i got no documentation or such stuff, hope my headers and test file are clear enough
cloning, merging or creating models should be easy and secure with this

www.target-of-victory.com/Download/DynamicModels.zip

greetz
Felix
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 06/01/12 06:20

@papenheimer wow that was pretty easy i never thought about that
great !
@masterq32 i will also look at yours ,always something to learn thanks for sharing
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/01/12 20:49

MasterQ32, thanks to your code, as well! laugh
Will have a closer look into it sometime,
for now, it is a bit too complicating for my limited purposes.

Wjbender and who is interested, I integrated position, scale and rotation into the code.
You can download the modified demo here: http://puppenheim.org/merge_models.zip

For those who prefer a look into the code without downloading anything,
here is the current code:
Code:
#include <acknex.h>
#include <default.c>
#include <d3d9.h>


function demo_init()
{
//	vec_set(sky_color,vector(10,0,0));
 	video_switch(10,32,0);

	vec_set(camera.x,vector(0,-400, 100));
 	camera.arc=90;
 	camera.pan=90;
 	camera.clip_near=1;

   fps_min=60;
 
 	def_move();
 	def_debug();
 	def_debug();
}

VECTOR temp1;
VECTOR center;

ENTITY* merge_ent(ENTITY* source1,ENTITY* source2)
{
	int vertices1=ent_status(source1,1);
	int vertices2=ent_status(source2,1);
	
	LPD3DXMESH mesh1;
	
	short *triangle_buffer1;
	short *triangle_buffer2;
	
	D3DVERTEX* vertex_buffer1;
	D3DVERTEX* vertex_buffer2;
	
	int triangles1;
	int triangles2;

	triangles1=ent_buffers(source1,0,0,&vertex_buffer1,&triangle_buffer1,NULL);
	triangles2=ent_buffers(source2,0,0,&vertex_buffer2,&triangle_buffer2,NULL);
	
	short* merged_triangle_buffer;
	D3DVERTEX* merged_vertex_buffer;

	int merged_triangles=triangles1+triangles2;
	int merged_vertices=vertices1+vertices2;
	
	int iterate;
	int offsetv=0;
	int offsett=0;
	
	vec_lerp(center.x, source1.x, source2.x, 0.5);//set a center between the two models origins
	
	D3DXCreateMesh(merged_triangles,merged_vertices,D3DXMESH_MANAGED,pvertexdecl,pd3ddev,&mesh1);
	if(mesh1!=NULL)
	{
		mesh1->LockVertexBuffer(0, (void**)&merged_vertex_buffer);
		mesh1->LockIndexBuffer (0, (void**)&merged_triangle_buffer);
		
		for (iterate=0;iterate<vertices1;iterate++)	
		{
			temp1.x=vertex_buffer1[iterate].x;
			temp1.y=vertex_buffer1[iterate].z;
			temp1.z=vertex_buffer1[iterate].y;
			
			vec_rotate(temp1.x, source1.pan);
			vec_scale(temp1.x, source1.scale_x);
			
			temp1.x *=source1.scale_x;
			temp1.y *=source1.scale_y;
			temp1.z *=source1.scale_z;
			
			temp1.x +=source1.x - center.x;
			temp1.y +=source1.y - center.y;
			temp1.z +=source1.z - center.z;
			
			merged_vertex_buffer[iterate].x=temp1.x+center.x;
			merged_vertex_buffer[iterate].y=temp1.z+center.z;
			merged_vertex_buffer[iterate].z=temp1.y+center.y;
			
			merged_vertex_buffer[iterate].u1=vertex_buffer1[iterate].u1;
			merged_vertex_buffer[iterate].v1=vertex_buffer1[iterate].v1;
			merged_vertex_buffer[iterate].u2=vertex_buffer1[iterate].u2;
			merged_vertex_buffer[iterate].v2=vertex_buffer1[iterate].v2;
			
		}
		
		offsetv+=vertices1;
		
		for (iterate=0;iterate<vertices2;iterate++)	
		{
			temp1.x=vertex_buffer1[iterate].x;
			temp1.y=vertex_buffer1[iterate].z;
			temp1.z=vertex_buffer1[iterate].y;
			
			vec_rotate(temp1.x, source2.pan);
			vec_scale(temp1.x, source2.scale_x);
			
			temp1.x *=source2.scale_x;
			temp1.y *=source2.scale_y;
			temp1.z *=source2.scale_z;
			
			temp1.x +=source2.x - center.x;
			temp1.y +=source2.y - center.y;
			temp1.z +=source2.z - center.z;
			
			merged_vertex_buffer[iterate+offsetv].x=temp1.x+center.x;
			merged_vertex_buffer[iterate+offsetv].y=temp1.z+center.z;
			merged_vertex_buffer[iterate+offsetv].z=temp1.y+center.y;
			
			merged_vertex_buffer[iterate+offsetv].u1=vertex_buffer2[iterate].u1;
			merged_vertex_buffer[iterate+offsetv].v1=vertex_buffer2[iterate].v1;
			merged_vertex_buffer[iterate+offsetv].u2=vertex_buffer2[iterate].u2;
			merged_vertex_buffer[iterate+offsetv].v2=vertex_buffer2[iterate].v2;
			
		}
		
		for (iterate=0;iterate<triangles1;iterate++)	
		{
			merged_triangle_buffer[iterate*3]=triangle_buffer1[iterate*3];
			merged_triangle_buffer[iterate*3+1]=triangle_buffer1[iterate*3+1];
			merged_triangle_buffer[iterate*3+2]=triangle_buffer1[iterate*3+2];
		}

		offsett+=triangles1;
		
		for (iterate=0;iterate<triangles2;iterate++)	
		{
			merged_triangle_buffer[(iterate+offsett)*3]=triangle_buffer2[iterate*3]+offsetv;
			merged_triangle_buffer[(iterate+offsett)*3+1]=triangle_buffer2[iterate*3+1]+offsetv;
			merged_triangle_buffer[(iterate+offsett)*3+2]=triangle_buffer2[iterate*3+2]+offsetv;
		}
	
		mesh1->UnlockVertexBuffer();
		mesh1->UnlockIndexBuffer();
	
		ENTITY* temp=ent_create(CUBE_MDL,nullvector,0);
		BMAP* bmp_source1 = ent_getskin(source1, 1);
		BMAP* bmp_source2 = ent_getskin(source2, 1);
		ent_setmesh(temp,mesh1,0,0);
		ent_setskin(temp, bmp_source1, 1);
		ent_setskin(temp, bmp_source2, 2);
		return temp;
	}
	return NULL;
}

function main()
{
	level_load("");
	wait(4);
	demo_init();
	
	ENTITY* ent1=ent_create("p.mdl",nullvector,0);
	ENTITY* ent2=ent_create("p.mdl",vector(120,0,0),0);
	ent2.pan =45;
	ent2.roll =20;
	ent2.tilt =15;
	ent1.tilt =10;
	ent1.scale_z = 0.2;

	ENTITY* merged=merge_ent(ent1,ent2);

	merged.z+=200;//set this to zero, if you wanna see whether the result is identical in angle, scale and position
	
//	ent_remove(dozer1);
//	wait(1);
//	ent_remove(dozer2);
//	wait(1);

	while(1)
	{
//		merged.pan+=1*time_step;
		wait(1);
	}
	
}


Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 06/02/12 08:20

@pappenheimer thanks i will download or copy code later on when im at my pc
currently im on my cellfone so i cant scroll the code block down but i was
wondering did you solve normals because i had another look at the code and realised
i never added the normals to the merged buffer . I gave it a shot but somehow it jusz didnt appear correct which i dont understand at all . Even if i swapped x and z . Or tried ent fixnormals
it just does not look correct .perhaps txesmi code he gave to evilsob for normals
could work as an alternative .

@masterq32 i looked a bit into the code you gave but didnt grasp how to merge
with it . Would you have to join buffers aswell?
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/02/12 08:30

I didn't test anything with the normals, it doesn't look like a problem at all, but that's probably, because of the models that I used for testing.

I realized that there is still something wrong with placing/rotating/scaling - I should have made more tests.
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 06/02/12 10:10

Your second assignment of temp needs to be set to vertexbuffer2 instead of vertexbuffer1
im reworking the function a bit also..

heres what i came up with but normals seems weird

Code:
#include <acknex.h>
#include <default.c>
#include <d3d9.h>


function demo_init()
{
 	video_switch(10,32,0);

	vec_set(camera.x,vector(0,-400, 100));
 	camera.arc=90;
 	camera.pan=90;
 	camera.clip_near=1;

   fps_min=60;
 
 	def_move();
 	def_move();
 	def_debug();
 	def_debug();
}

VECTOR temp1;

ENTITY* merge_ent(ENTITY* source1,ENTITY* source2)
{
	int vertices_source1=ent_status(source1,1);
	int vertices_source2=ent_status(source2,1);
	
	LPD3DXMESH mesh;
	
	short *tbuffer_source1;
	short *tbuffer_source2;
	
	D3DVERTEX* vbuffer_source1;
	D3DVERTEX* vbuffer_source2;
	
	int triangles_source1;
	int triangles_source2;

	triangles_source1=ent_buffers(source1,0,0,&vbuffer_source1,&tbuffer_source1,NULL);
	triangles_source2=ent_buffers(source2,0,0,&vbuffer_source2,&tbuffer_source2,NULL);
	
	short* merged_tbuffer;
	D3DVERTEX* merged_vbuffer;

	int merged_triangles=triangles_source1+triangles_source2;
	int merged_vertices=vertices_source1+vertices_source2;
	
	int iterate;
	int offsetv=0;
	int offsett=0;
	
	D3DXCreateMesh(merged_triangles,merged_vertices,D3DXMESH_MANAGED,pvertexdecl,pd3ddev,&mesh);
	if(mesh!=NULL)
	{
		mesh->LockVertexBuffer(0, (void**)&merged_vbuffer);
		mesh->LockIndexBuffer (0, (void**)&merged_tbuffer);
		
		for (iterate=0;iterate<vertices_source1;iterate++)	
		{
			temp1.x=source1.x+vbuffer_source1[iterate].x*source1.scale_x;
			temp1.y=source1.y+vbuffer_source1[iterate].y*source1.scale_z;
			temp1.z=source1.z+vbuffer_source1[iterate].z*source1.scale_y;
			
			VECTOR final;
			final.x=temp1.x;
			final.y=temp1.z;
			final.z=temp1.y;
			vec_rotate(final.x,source1.pan);

			merged_vbuffer[iterate].x=final.x;
			merged_vbuffer[iterate].y=final.z;
			merged_vbuffer[iterate].z=final.y;
			
			merged_vbuffer[iterate].nx=vbuffer_source1[iterate].nx;
			merged_vbuffer[iterate].nz=vbuffer_source1[iterate].ny;
			merged_vbuffer[iterate].ny=vbuffer_source1[iterate].nz;

			merged_vbuffer[iterate].u1=vbuffer_source1[iterate].u1;
			merged_vbuffer[iterate].v1=vbuffer_source1[iterate].v1;
			merged_vbuffer[iterate].u2=vbuffer_source1[iterate].u2;
			merged_vbuffer[iterate].v2=vbuffer_source1[iterate].v2;
			
		}
		
		offsetv+=vertices_source1;
		
		for (iterate=0;iterate<vertices_source2;iterate++)	
		{
			temp1.x=source2.x+vbuffer_source2[iterate].x*source2.scale_x;
			temp1.y=source2.y+vbuffer_source2[iterate].y*source2.scale_z;
			temp1.z=source2.z+vbuffer_source2[iterate].z*source2.scale_y;
			
			VECTOR final;
			final.x=temp1.x;
			final.y=temp1.z;
			final.z=temp1.y;
			vec_rotate(final.x,source2.pan);
				
			merged_vbuffer[iterate+offsetv].x=final.x;
			merged_vbuffer[iterate+offsetv].y=final.z;
			merged_vbuffer[iterate+offsetv].z=final.y;
			
			merged_vbuffer[iterate+offsetv].nx=vbuffer_source2[iterate].nx;
			merged_vbuffer[iterate+offsetv].nz=vbuffer_source2[iterate].ny;
			merged_vbuffer[iterate+offsetv].ny=vbuffer_source2[iterate].nz;

			merged_vbuffer[iterate+offsetv].u1=vbuffer_source2[iterate].u1;
			merged_vbuffer[iterate+offsetv].v1=vbuffer_source2[iterate].v1;
			merged_vbuffer[iterate+offsetv].u2=vbuffer_source2[iterate].u2;
			merged_vbuffer[iterate+offsetv].v2=vbuffer_source2[iterate].v2;
			
		}
		
		for (iterate=0;iterate<triangles_source1;iterate++)	
		{
			merged_tbuffer[iterate*3]  =tbuffer_source1[iterate*3];
			merged_tbuffer[iterate*3+1]=tbuffer_source1[iterate*3+1];
			merged_tbuffer[iterate*3+2]=tbuffer_source1[iterate*3+2];
		}

		offsett+=triangles_source1;
		
		for (iterate=0;iterate<triangles_source2;iterate++)	
		{
			merged_tbuffer[(iterate+offsett)*3]  =tbuffer_source2[iterate*3]  +offsetv;
			merged_tbuffer[(iterate+offsett)*3+1]=tbuffer_source2[iterate*3+1]+offsetv;
			merged_tbuffer[(iterate+offsett)*3+2]=tbuffer_source2[iterate*3+2]+offsetv;
		}
	
		mesh->UnlockVertexBuffer();
		mesh->UnlockIndexBuffer();
	
		ENTITY* merged_entity=ent_create(CUBE_MDL,nullvector,0);
		BMAP* bmp_source1 = ent_getskin(source1, 1);
		BMAP* bmp_source2 = ent_getskin(source2, 1);
		ent_setmesh(merged_entity,mesh,0,0);
		ent_setskin(merged_entity, bmp_source1, 1);
		ent_setskin(merged_entity, bmp_source2, 2);
		return merged_entity;
	}
	return NULL;
}

function main()
{
	level_load("");
	wait(4);
	demo_init();
	
	ENTITY* ent1=ent_create("dozer.mdl",nullvector,0);
	ENTITY* ent2=ent_create("dozer.mdl",vector(120,0,0),0);
	ent2.pan =45;
	ent2.roll =20;
	ent2.tilt =15;
	ent1.tilt =10;
	ent1.scale_z = 0.5;

	ENTITY* merged=merge_ent(ent1,ent2);
	merged.z+=800;//set this to zero, if you wanna see whether the result is identical source2 angle, scale and position

//	ent_remove(ent1);
//	wait(1);
//	ent_remove(ent2);
//	wait(1);

	while(1)
	{
	//	merged.pan+=1*time_step;
		wait(1);
	}
	
}



it seems correct now ,the scaling
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/02/12 14:34

Still no correct normals. Tried whether the material could be the reason, but assigning a new material to all models didn't chenge the difference of the shading between the original models and the merged model.
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 06/02/12 14:54

Yeah im totaly missing whats going wrong here .what if the attribute
buffer gets added i dnt know how to further help this function towards
victory .just not enough experience yet

EDIT:
another little stab at it...
heres a function txesmi has written for normal calculation
perhaps if the merged entity's normals gets recalculated with it?
i almost want to point out that perhaps the normals points to the unrotated/unscaled/unoffset'd mesh but im not sure
Code:
function true_fixnormals ( ENTITY *ent )
{
	D3DVERTEX *vb;
	short *tb;
	long *at;
	int i, ii;
	VECTOR vNormal, vOldNormal, v1, v2, v3;
	
	int tnum = ent_status ( ent, 4 );
	int vnum = ent_status ( ent, 1 );
	
	ent_buffers ( ent, 0, 0, &vb, &tb, &at );
	
	for ( i=0; i<vnum; i++ ) // reset normals
	{
		vb[i].nx = vb[i].ny = vb[i].nz = 0;
	}
	
	for ( i=0; i<tnum*3; i+=3 ) // compute normals
	{
		vec_set ( v1, vector ( vb[tb[i]].x, vb[tb[i]].z, vb[tb[i]].y ) ); // we can't operate with floats as vectors
		vec_set ( v2, vector ( vb[tb[i+1]].x, vb[tb[i+1]].z, vb[tb[i+1]].y ) );
		vec_set ( v3, vector ( vb[tb[i+2]].x, vb[tb[i+2]].z, vb[tb[i+2]].y ) );
		
		vec_cross ( vNormal, vec_diff ( NULL, v3, v1 ), vec_diff ( NULL, v2, v1 ) );
		vec_normalize ( vNormal, 1 );
		
		for ( ii=0; ii<3; ii++ ) // add the new normal to each vertex
		{
			vec_set ( vOldNormal, vector ( vb[tb[i+ii]].nx, vb[tb[i+ii]].nz, vb[tb[i+ii]].ny ) );
			vec_add ( vOldNormal, vNormal );
			vec_normalize ( vOldNormal, 1 );
			vb[tb[i+ii]].nx = vOldNormal.x;
			vb[tb[i+ii]].ny = vOldNormal.z;
			vb[tb[i+ii]].nz = vOldNormal.y;
		}
	}
}


Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/02/12 15:59

Originally Posted By: Wjbender

another little stab at it...
heres a function txesmi has written for normal calculation
perhaps if the merged entity's normals gets recalculated with it?


Thanks for the code, and hail to txesmi for the cool snippet! laugh

We've got it!

Insert his function, and put the following at the end within the main function.

true_fixnormals(merged);
Posted By: EvilSOB

Re: Merge 2 Meshes/Entities during game... - 06/02/12 16:23

I think you have hit the nail on the head there Wjbender.
i suspect the normals are being 'corrupted' during the merge.

Im afraid (and sorry) I dont have the time to look at this more closely ATM,
but Im juggling too many other jobs at this time already.


OFF-HAND, I dont think using txesmi's calculaions is a good idea,
because if either of the meshes had 'custom' normals, re-calculating
them will erase any customisation/weightings.

BUT, youve sucessfully spotted that the vertices needed to be rotated,
and you seem to have implemented that OK, but normals are also VERY
angle-dependant, so they need rotated too.

I have never actually tried this, and so it is only an extrapolation of the
little that I THINK I know.

So try this UNTESTED code and see how we go.
This is the 'source1' mesh vertex loop, and you will need to do the same
calculation in the 'source2's loop also.
Code:
...
		for (iterate=0;iterate<vertices_source1;iterate++)	
		{
			temp1.x=source1.x+vbuffer_source1[iterate].x*source1.scale_x;
			temp1.y=source1.y+vbuffer_source1[iterate].y*source1.scale_z;
			temp1.z=source1.z+vbuffer_source1[iterate].z*source1.scale_y;
			
			VECTOR final;
			final.x=temp1.x;
			final.y=temp1.z;
			final.z=temp1.y;
			vec_rotate(final.x,source1.pan);

			merged_vbuffer[iterate].x=final.x;
			merged_vbuffer[iterate].y=final.z;
			merged_vbuffer[iterate].z=final.y;

			//	=========  START of EvilSOB's suggestion	===============
			VECTOR new_norm;
			new_norm.x = vbuffer_source1[iterate].nx;
			new_norm.y = vbuffer_source1[iterate].ny;
			new_norm.z = vbuffer_source1[iterate].nz;
			vec_rotate(new_norm, source1.pan);
			//  vec_normalize(new_norm, 1);   //maybe?!?
			//
			merged_vbuffer[iterate].nx = new_norm.nx;
			merged_vbuffer[iterate].ny = new_norm.ny;
			merged_vbuffer[iterate].nz = new_norm.nz;
			//	=========  END of EvilSOB's suggestion	===============
			
			merged_vbuffer[iterate].u1=vbuffer_source1[iterate].u1;
			merged_vbuffer[iterate].v1=vbuffer_source1[iterate].v1;
			merged_vbuffer[iterate].u2=vbuffer_source1[iterate].u2;
			merged_vbuffer[iterate].v2=vbuffer_source1[iterate].v2;
			
		}
...

These following points are listed in priority order, as best as I can figure...

Bear in mind, this is code 'off the top of my head', so firstly, beware of syntax or bracket errors.

Secondly, it is POSSIBLE this code will need to have the ny/nz swapovers for the vec-rotate, but I suspect not,
so this code does NOT have the swapping implemented yet, try it as-is first.

And thirdly, Im not sure of vec-rotate working with normals... I just dont understand the maths inside normals
enough to be sure, so if things still wont look right, try some other vec-rotational functions,
like vec_rotateback() or ang_add, or even vec_add/vec_sub. I strongly suggest also using
vec_normalize on these results if you 'break away' from the original vec_rotate.

And in combination with these, it may be worth putting in a vec_normalize between
the vec-rotating and the storing into merged_vbuffer. But I think this is probably un-necessary.
(I have shown it in the code but have left it commented-out initially)


Best of luck... and I hope this helps...

I am watching this thread with interest...


[EDIT] I missed Pappenheimer's post, and its good its 'fixed', but hopefully someone will try my suggestions anyway...



Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/02/12 19:14

Thanks for your input, EvilSOB!

It works with the following modification with my testmodel, a SimplySid.mdl from otter,
but it throws an error message, when I try it with the dozer.mdl of Wjbender.
Code:
for (iterate=0;iterate<vertices_source1;iterate++)	
		{
			temp1.x=source1.x+vbuffer_source1[iterate].x*source1.scale_x;
			temp1.y=source1.y+vbuffer_source1[iterate].y*source1.scale_z;
			temp1.z=source1.z+vbuffer_source1[iterate].z*source1.scale_y;
			
			//	=========  START of EvilSOB's suggestion	===============
			VECTOR new_norm;
			new_norm.x = vbuffer_source1[iterate].nx;
			new_norm.y = vbuffer_source1[iterate].ny;
			new_norm.z = vbuffer_source1[iterate].nz;
			vec_rotate(new_norm, source1.pan);
			//  vec_normalize(new_norm, 1);   //maybe?!?
			//
			merged_vbuffer[iterate].nx = new_norm.x;
			merged_vbuffer[iterate].ny = new_norm.z;
			merged_vbuffer[iterate].nz = new_norm.y;
			//	=========  END of EvilSOB's suggestion	===============
			VECTOR final;
			final.x=temp1.x;
			final.y=temp1.z;
			final.z=temp1.y;
			vec_rotate(final.x,source1.pan);

			merged_vbuffer[iterate].x=final.x;
			merged_vbuffer[iterate].y=final.z;
			merged_vbuffer[iterate].z=final.y;
			
//			merged_vbuffer[iterate].nx=vbuffer_source1[iterate].nx;
//			merged_vbuffer[iterate].nz=vbuffer_source1[iterate].ny;
//			merged_vbuffer[iterate].ny=vbuffer_source1[iterate].nz;

			merged_vbuffer[iterate].u1=vbuffer_source1[iterate].u1;
			merged_vbuffer[iterate].v1=vbuffer_source1[iterate].v1;
			merged_vbuffer[iterate].u2=vbuffer_source1[iterate].u2;
			merged_vbuffer[iterate].v2=vbuffer_source1[iterate].v2;
			
		}
		
		offsetv+=vertices_source1;
		
		for (iterate=0;iterate<vertices_source2;iterate++)	
		{
			temp1.x=source2.x+vbuffer_source2[iterate].x*source2.scale_x;
			temp1.y=source2.y+vbuffer_source2[iterate].y*source2.scale_z;
			temp1.z=source2.z+vbuffer_source2[iterate].z*source2.scale_y;
			
			//	=========  START of EvilSOB's suggestion	===============
			VECTOR new_norm;
			new_norm.x = vbuffer_source2[iterate+offsetv].nx;
			new_norm.y = vbuffer_source2[iterate+offsetv].ny;
			new_norm.z = vbuffer_source2[iterate+offsetv].nz;
			vec_rotate(new_norm, source2.pan);
			//  vec_normalize(new_norm, 1);   //maybe?!?
			//
			merged_vbuffer[iterate+offsetv].nx = new_norm.x;
			merged_vbuffer[iterate+offsetv].ny = new_norm.z;
			merged_vbuffer[iterate+offsetv].nz = new_norm.y;
			//	=========  END of EvilSOB's suggestion	===============
			VECTOR final;
			final.x=temp1.x;
			final.y=temp1.z;
			final.z=temp1.y;
			vec_rotate(final.x,source2.pan);
				
			merged_vbuffer[iterate+offsetv].x=final.x;
			merged_vbuffer[iterate+offsetv].y=final.z;
			merged_vbuffer[iterate+offsetv].z=final.y;
			
//			merged_vbuffer[iterate+offsetv].nx=vbuffer_source2[iterate].nx;
//			merged_vbuffer[iterate+offsetv].nz=vbuffer_source2[iterate].ny;
//			merged_vbuffer[iterate+offsetv].ny=vbuffer_source2[iterate].nz;

			merged_vbuffer[iterate+offsetv].u1=vbuffer_source2[iterate].u1;
			merged_vbuffer[iterate+offsetv].v1=vbuffer_source2[iterate].v1;
			merged_vbuffer[iterate+offsetv].u2=vbuffer_source2[iterate].u2;
			merged_vbuffer[iterate+offsetv].v2=vbuffer_source2[iterate].v2;
			
		}


Posted By: EvilSOB

Re: Merge 2 Meshes/Entities during game... - 06/03/12 00:06

I havent tested anything, but I suspect it is the source2 vertex loop.

Such a simple fault, maybe even a typo...

Code:
Find the lines :
new_norm.x = vbuffer_source2[iterate+offsetv].nx;
new_norm.y = vbuffer_source2[iterate+offsetv].ny;
new_norm.z = vbuffer_source2[iterate+offsetv].nz;

and replace them with ::
new_norm.x = vbuffer_source2[iterate].nx;
new_norm.y = vbuffer_source2[iterate].ny;
new_norm.z = vbuffer_source2[iterate].nz;

And that will fix the crashes at least...
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/03/12 08:46

Ups, my fault! You are right.

Maybe, it is simply the dozer.mdl, because the shading of the original model looks more wired to me than the merged model.

Is it possible, that the vertices that are split in the original are melted in the merged one?

In the code I have to write different vertices to get the different vertices of the uvs, where do I put the information that they are split in the 3d as well?
Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 06/04/12 22:02

It looks really interesting. Good work guys!

But if I want to merge the already merged Entity with an other, then it's not right working.
Posted By: EvilSOB

Re: Merge 2 Meshes/Entities during game... - 06/05/12 13:18

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();	
	//
}


Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 06/05/12 14:01

Hey EvilSOB,

thank you for your informations. laugh
Your code is very useful for me and I think also for many other people here!
I will tell you, if something is wrong.
Thank you a lot.
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/05/12 21:29

Did you try to merge several _different_ models?
When I try to add a different model as well, it seems to stay on its own.
At least, it is not included in the general collision box, and its placing seems off...
Posted By: EvilSOB

Re: Merge 2 Meshes/Entities during game... - 06/06/12 05:45

Benni :: No probs dude. If I find more time, I will try improving it.

Pappenheimer :: Did I try 'different' models? Yes and No.
Yes - I tried others, but No - cause they all FAILED, as I expected.

This function is still a VERY limited work-in-progress. I was just posting where
I had gotten to when I ran out of time. Im busy doing some HEAVY work with Esper
and only did this code to have a break from his, to clear my mental buffers...

Other models just wont work AT THIS TIME, because this process cannot handle
multiple skins. Only the first one it ever sees.
I have not yet figured out how directx/acknex stores the 'which skin' information in the attribute table.

I know how directx is SUPPOSED to store it, but it doesnt seem to translate
correctly when I do the ent_setmesh() stage, and if I try updating this
information AFTER the ent_setmesh(), everything except skin1 is invisible...
And I havent the time to research this at the moment Im afraid...

So, because it can only handle one skin, that why I only botherd trying with
the same model time after time. Cause they all have the same skin that way,
and so the process works in its limited fashion.
And this limited fashion SOUNDED like it was all Benni needed, and its HIS thread...


So, I left it at that. IF I get time later, I will come back to this and
improve upon what it can do, but I dont know when that will be...
Posted By: Pappenheimer

Re: Merge 2 Meshes/Entities during game... - 06/06/12 15:52

EvilSOB, everything is fine. laugh Thank you for your snippet and explanations!

I didn't want to force you to do anything, I just thought to give feedback,
because you wrote "and CERTAINLY let me know if it doesnt
work in certain situations!" laugh

BTW, the one skin only thing is no problem to me.
Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 07/02/12 08:16

Hello,
I have a Problem with the code. I want to Merge more then one Entity, so I do like this:

Everything is good working:
Code:
function main()
{
	level_load("");
	wait(2);
	wait(1);
	demo_init();
	
	ENTITY* ent1=ent_create("p.mdl",nullvector,0);
	ENTITY* ent2=ent_create("p.mdl",vector(120,0,0),0);

	ENTITY* merged=merge_ent(ent1,ent2);
	merged.z+=200;//set this to zero, if you wanna see whether the result is identical in angle, scale and position
	int i;
	for(i=0;i<100;i++)
	{
		merged=merge_ent(merged,ent2);
		wait(1);	
	}
}


But if I paste collision_mode=0; after the first wait, it crashes in merge ent:

Code:
function main()
{
	level_load("");
	wait(2);
	collision_mode=0;
	wait(1);
	demo_init();
	
	ENTITY* ent1=ent_create("p.mdl",nullvector,0);
	ENTITY* ent2=ent_create("p.mdl",vector(120,0,0),0);

	ENTITY* merged=merge_ent(ent1,ent2);
	merged.z+=200;//set this to zero, if you wanna see whether the result is identical in angle, scale and position
	int i;
	for(i=0;i<100;i++)
	{
		merged=merge_ent(merged,ent2);
		wait(1);	
	}
}



Does anyone know where the Problem is? Without collision_mode=0; it's good working. But I need to set it to 0.


Posted By: Damocles

Re: Merge 2 Meshes/Entities during game... - 07/02/12 11:10

"entities are created ... without a collision model"

8.05 When set to 0 after level loading, all subsequent entities are created with PASSABLE flag and without a collision model. They are created faster and consume less memory this way, but can't be used as colliders or obstacles. When setting collision_mode to nonzero and resetting PASSABLE, the entity's collision model is created afterwards in the next frame cycle. The entities can then perform normal collision detection.


Maybe some nullpointer while merging since the collision model is not created.


Can you try it with ent_morph too.
Maybe it causes the same crash.
Posted By: EvilSOB

Re: Merge 2 Meshes/Entities during game... - 07/02/12 11:19

Im just passing through, cause I still dont have much time,
but try this updated (but utterly untested) version of ent_merge.

It SHOULD by-pass the collision_mode problem.
Click to reveal..
Code:
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);
}


Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 07/02/12 11:29

hm, it say's D3DXConcatenateMeshes - undeclared identifer
Posted By: Bone

Re: Merge 2 Meshes/Entities during game... - 07/02/12 17:06

Take the code from page 4 and replace the ent_merge function with the ent_merge function above
Posted By: EvilSOB

Re: Merge 2 Meshes/Entities during game... - 07/02/12 17:11

You shouldnt get that if my original declaration for it is still
included before my ent_merge function.

Put this following above my function and it should be fine.
Click to reveal..
Code:
HRESULT WINAPI D3DXConcatenateMeshes
(	LPD3DXMESH		*ppMeshes,
	UINT				NumMeshes, 
	DWORD				Options, 
	void*				junk1,
	void*				junk2,
	CONST D3DVERTEXELEMENT9	*pDecl, 
	LPDIRECT3DDEVICE9			pD3DDevice, 
	LPD3DXMESH		*ppMeshOut
);


And also remember to have the "#include <d3d9.h>" at the top of you main script.


Otherwise post the whole of your script and we will see what we can see...
Posted By: Benni003

Re: Merge 2 Meshes/Entities during game... - 07/02/12 17:21

Thanks, now it's working. And I know, d3d9.h was included wink
Posted By: djfeeler

Re: Merge 2 Meshes/Entities during game... - 08/20/14 05:34

Hello !

Your code is very great ! I would like to know if we can remove an element that has been added ?

Thanks in advance !

Djfeeler
Posted By: Wjbender

Re: Merge 2 Meshes/Entities during game... - 09/27/14 10:25

your best option is to rather use the TUST library

here is something i am busy with

Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>

#define PRAGMA_PATH "tust"
///////////////////////////////
#include "tust.h"

//max units
#define population 21000/12

//step in units of unit_space
var unit_space=16;

typedef struct cluster_unit
{
	VECTOR pos;
	LPD3DXMESH mesh;
	int uid;
}cluster_unit;


//build the model from the cluster models
void build_cluster_units(List* cluster,DynamicModel *model)
{
	if(model!=NULL && cluster!=NULL)
	{
		memset(model,0,sizeof(DynamicModel));
		ListItem *it = cluster->first;
		for(it = cluster->first; it != NULL; it = it->next)
		{
			cluster_unit* mycluster=(cluster_unit*)it.data;
			dmdl_add_mesh(model,mycluster.mesh,mycluster.pos);
		} 
		list_end_iterate(it);
	}
}

//add a unit to the cluster
//the cluster model must be re-build with build_cluster_units
void add_cluster_unit(List *cluster,ENTITY *ent,int uid)
{
	cluster_unit *mycluster=malloc(sizeof(cluster_unit));
	
	vec_set(mycluster.pos,ent.x);
	mycluster.mesh=ent_getmesh(ent,0,0);
	mycluster.uid=uid;
	
	list_add(cluster,(cluster_unit*)mycluster);
	sys_free(mycluster);
}

//remove a unit from the cluster 
//the cluster model has to be re-build with build_cluster_units after
void remove_cluster_unit(List *cluster,int uid)
{
	ListItem *it = cluster->first;
	for(it = cluster->first; it != NULL; it = it->next)
	{
		cluster_unit* mycluster=(cluster_unit*)it.data;
		
		if(mycluster.uid==uid)list_remove(cluster,it.data);
	} 
	list_end_iterate(it);
}

function main()
{
	max_entities =50000;
	max_particles=50000;
	
	vec_set(screen_size,vector(800,600,0));
	vec_set(screen_color,vector(1,1,1)); // dark blue
	vec_set(sky_color,vector(1,1,1)); // dark blue
	
	video_window(NULL,NULL,0,"random generator");
	 
	level_load("");
	
	random_seed(500);
	
	while(total_frames<1)wait(1);
	camera.x=-100;
	//camera.z=1000;
	//camera.tilt-=90;
	def_debug();def_debug();def_move();


////////////////////////////////////////////////
//populate the cluster list with entity data

	//position of placement
	VECTOR pos;
	vec_set(pos,nullvector);
	int i;	

	DynamicModel *model =dmdl_create();
	List *cluster=list_create();
	

	for(i=0;i<population;i+=1)
	{
		
		ENTITY* cube=ent_create(CUBE_MDL,pos,NULL);
		
		//store cluster_unit in the list 
		add_cluster_unit(cluster,cube,i);
		
		//remove entity
		ptr_remove(cube);
		
		if(pos.x<unit_space * 50)pos.x+=unit_space;
		else 
		{
			pos.y+=unit_space;
			pos.x=0;
		}
		
	}


////////////////////////////////////////////////
//merge and re-build cluster units into single model 
	build_cluster_units(cluster,model);

	//create merged entity
	ENTITY *cluster_ent=dmdl_create_instance(model,nullvector,NULL);
	
////////////////////////////////////////////////


//remove some units from cluster
for(i=0;i<100;i++)	remove_cluster_unit(cluster,integer(random(population)) );

////////////////////////////////////////////////
//merge and re-build cluster units into single model 
	build_cluster_units(cluster,model);

	//create merged entity
	ENTITY *cluster_ent1=dmdl_create_instance(model,vector(0,-600,0),NULL);
	
////////////////////////////////////////////////


	//remove dynamic model
	sys_free(model);
	//remove list
	sys_free(cluster);
	
}


© 2024 lite-C Forums