3 registered members (Ayumi, Akow, AndrewAMD),
1,505
guests, and 9
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: MasterQ32]
#402247
06/01/12 06:20
06/01/12 06:20
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
@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
Compulsive compiler
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: Wjbender]
#402280
06/01/12 20:49
06/01/12 20:49
|
Joined: Sep 2003
Posts: 5,900 Bielefeld, Germany
Pappenheimer
Senior Expert
|
Senior Expert
Joined: Sep 2003
Posts: 5,900
Bielefeld, Germany
|
MasterQ32, thanks to your code, as well! 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.zipFor those who prefer a look into the code without downloading anything, here is the current 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);
}
}
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: Pappenheimer]
#402292
06/02/12 08:20
06/02/12 08:20
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
@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?
Compulsive compiler
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: Pappenheimer]
#402296
06/02/12 10:10
06/02/12 10:10
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
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
#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
Last edited by Wjbender; 06/02/12 11:41.
Compulsive compiler
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: Pappenheimer]
#402317
06/02/12 14:54
06/02/12 14:54
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
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
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;
}
}
}
Last edited by Wjbender; 06/02/12 15:41.
Compulsive compiler
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: Wjbender]
#402321
06/02/12 15:59
06/02/12 15:59
|
Joined: Sep 2003
Posts: 5,900 Bielefeld, Germany
Pappenheimer
Senior Expert
|
Senior Expert
Joined: Sep 2003
Posts: 5,900
Bielefeld, Germany
|
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! We've got it! Insert his function, and put the following at the end within the main function. true_fixnormals(merged);
|
|
|
Re: Merge 2 Meshes/Entities during game...
[Re: Wjbender]
#402324
06/02/12 16:23
06/02/12 16:23
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
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.
...
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...
Last edited by EvilSOB; 06/02/12 16:26.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
|