// Configure <br/> void trianglemeshdata: addvertexdata (const vertexdata * vertex_data, <br/> const vertexdata * blended_data, <br/> const mesh: indexmap * indexmap) <br/>{< br/> If (! Vertex_data) <br/> return; </P> <p> const vertexdata * Data = (blended_data )? Blended_data: vertex_data; </P> <p> const unsigned int prev_size = _ vertex_count; <br/> _ vertex_count + = (unsigned INT) Data-> vertexcount; </P> <p> ogre: vector3 * tmp_vert = new ogre: vector3 [_ vertex_count]; <br/> If (_ vertices) <br/>{< br/> memcpy (tmp_vert, _ vertices, sizeof (vector3) * prev_size); <br/> Delete [] _ vertices; <br/>}< br/> _ vertices = tmp_vert; </P> <p> // get the positional buffer element <BR/>{< br/> const ogre: vertexelement * poselem = data-> vertexdeclaration-> findelementbysemantic (Ogre: ves_position); <br/> ogre :: hardwarevertexbuffersharedptr vbuf = data-> vertexbufferbinding-> getbuffer (poselem-> getsource (); <br/> const unsigned int vsize = (unsigned INT) vbuf-> getvertexsize (); </P> <p> unsigned char * vertex = static_cast <unsigned char *> (vbuf-> lock (Ogre: hardwarebuffer: hbl_read_o Nly); <br/> float * PREAL; <br/> ogre: vector3 * curvertices = & _ vertices [prev_size]; <br/> const unsigned int vertexcount = (unsigned INT) Data-> vertexcount; <br/> for (unsigned Int J = 0; j <vertexcount; ++ J) <br/>{< br/> poselem-> basevertexpointertoelement (vertex, & PREAL); <br/> vertex + = vsize; </P> <p> curvertices-> X = (* PREAL ++); <br/> curvertices-> Y = (* PREAL ++ ); <br/> curvertices-> Z = (* PREA L ++); </P> <p> // * curvertices = _ transform * (* curvertices); </P> <p> curvertices ++; <br/>}< br/> vbuf-> unlock (); <br/>}</P> <p> // get the bone index element <br/> If (_ entity & _ entity-> hasskeleton ()) <br/>{</P> <p> ogre: meshptr mesh = _ entity-> getmesh (); </P> <p> const ogre :: vertexelement * bneelem = vertex_data-> vertexdeclaration-> findelementbysemantic (Ogre: ves_blend_indices); <br/> assert (bnee Lem); <br/>{< br/> ogre: hardwarevertexbuffersharedptr vbuf = vertex_data-> vertexbufferbinding-> getbuffer (bneelem-> getsource ()); <br/> const unsigned int vsize = (unsigned INT) vbuf-> getvertexsize (); <br/> unsigned char * vertex = static_cast <unsigned char *> (vbuf-> lock (Ogre: hardwarebuffer: hbl_read_only )); </P> <p> unsigned char * pbone; </P> <p> If (! _ Bone_mapping) <br/> _ bone_mapping = new bonemapping (); <br/> bonemapping: iterator I; </P> <p> ogre :: vector3 * curvertices = & _ vertices [prev_size]; </P> <p> const unsigned int vertexcount = (unsigned INT) vertex_data-> vertexcount; <br/> for (unsigned Int J = 0; j <vertexcount; ++ J) <br/>{< br/> bneelem-> basevertexpointertoelement (vertex, & pbone ); <br/> vertex + = vsize; </P> <p> const unsigned char currb One = (indexmap )? (* Indexmap) [* pbone]: * pbone; <br/> I = _ bone_mapping-> Find (currbone); <br/> vector3array * l = 0; <br/> if (I ==_ bone_mapping-> end () <br/>{< br/> L = new vector3array; <br/> _ bone_mapping-> insert (bonemappingkey (currbone, L )); <br/>}< br/> else <br/>{< br/> L = I-> second; <br/>}</P> <p> L-> push_back (* curvertices); </P> <p> curvertices ++; <br/>}< br/> vbuf-> unlock (); <br/>}< br/>Setting the physical effects of terrain from Ogre can be divided into two categories:
The first type is easy to read from the height chart and then create a fixed index sequence, and create the terrain by yourself;
The second type is entity creation. It is very simple to say that the mesh model is created. The advantage of this is that you do not need to render it yourself...
Currently, only the second method is implemented. In fact, the essence is to extract vertex information and index information from the mesh and then fill in
Nxtrianglemeshdesc * trianglemeshdesc; the rest is nothing more than generating the corresponding model;
Nxactor * physxtool: createtrianglemesh (trianglemeshdata * data, nxphysicssdk * gphysicssdk, nxscene * gscene) </P> <p >{< br/> *** trianglemeshdesc; <br/> // create descriptor for triangle mesh <br/> trianglemeshdesc = new nxtrianglemeshdesc (); <br/> trianglemeshdesc-> numvertices = data-> getvertexcount (); <br/> trianglemeshdesc-> pointstridebytes = sizeof (nxvec3); <br/> trianglemeshdesc-> points = (void *) Data-> getvertices (); <br/> trianglemeshdesc-> numtriangles = data-> getindexcount ()/3; <br/> trianglemeshdesc-> flags = 0; <br/> trianglemeshdesc-> triangles = (void *) Data-> getindices (); <br/> trianglemeshdesc-> trianglestridebytes = 3 * sizeof (nxu32 ); </P> <p> trianglemeshdesc-> heightfieldverticalaxis = nx_y; <br/> trianglemeshdesc-> heightfieldverticalextent =-1000.0f; </P> <p> // The actor has one shape, a triangle mesh <br/> nxinitcooking (); <br/> memorywritebuffer Buf; </P> <p> bool status = nxcooktrianglemesh (* trianglemeshdesc, Buf); <br/> nxtrianglemesh * pmesh; <br/> If (Status) <br/>{< br/> pmesh = gphysicssdk-> createtrianglemesh (memoryreadbuffer (BUF. data); <br/>}< br/> else <br/>{< br/> assert (false); <br/> pmesh = NULL; <br/>}< br/> nxclosecooking (); <br/> // create trianglemesh above code segment. </P> <p> nxtrianglemeshshapedesc tmsd; <br/> tmsd. meshdata = pmesh; <br/> tmsd. userdata = trianglemeshdesc; <br/> tmsd. localpose. T = nxvec3 (0, 0, 0); <br/> tmsd. meshpagingmode = nx_mesh_paging_auto; <br/> tmsd. shapeflags = nx_sf_feature_indices; <br/> nxactordesc actordesc; </P> <p> assert (tmsd. isvalid (); <br/> actordesc. shapes. pushback (& tmsd); <br/> If (pmesh) <br/> return gscene-> createactor (actordesc); <br/> else <br/> return NULL; <br/>}< br/>
The returned actor can be used directly. Because no body is set, the default value is static. When an object falls onto the surface, the system automatically performs collision detection;
The key to this implementation is the extraction of mesh data, which is a piece of code "plagiarized" from ogreode and demonstrates how to extract vertex data and index data;
// Const bool ishwanimated = isskeletonanimated & entity-> ishardwareanimationenabled (); <br/> If (isskeletonanimated) <br/>{< br/> _ entity-> addsoftwareanimationrequest (false); <br/> _ entity-> _ updateanimation (); <br/>}</P> <p> If (_ entity-> getmesh ()-> sharedvertexdata) <br/>{< br/> If (! Isskeletonanimated) <br/> addvertexdata (_ entity-> getmesh ()-> sharedvertexdata); <br/> else <br/> addvertexdata (_ entity-> getmesh () -> sharedvertexdata, <br/> _ entity-> _ getskelanimvertexdata (), <br/> & _ entity-> getmesh ()-> sharedblendindextoboneindexmap ); <br/>}</P> <p> for (unsigned int I = 0; I <_ entity-> getnumsubentities (); ++ I) <br/>{< br/> submesh * sub_mesh = _ entity-> getsubentity (I)-> getsubmesh (); </P> <p> If (! Sub_mesh-> usesharedvertices) <br/>{< br/> addindexdata (sub_mesh-> indexdata, _ vertex_count); </P> <p> If (! Isskeletonanimated) <br/> addvertexdata (sub_mesh-> vertexdata); <br/> else <br/> addvertexdata (sub_mesh-> vertexdata, <br/> _ entity-> getsubentity (I)-> _ getskelanimvertexdata (), <br/> & sub_mesh-> blendindextoboneindexmap ); <br/>}< br/> else <br/> {<br/> addindexdata (sub_mesh-> indexdata); <br/>}</P> <p>}
Addindex and addvertex write data to the class respectively:
Void trianglemeshdata: addindexdata (indexdata * data, const unsigned int offset) <br/>{< br/> const unsigned int prev_size = _ index_count; <br/> _ index_count + = (unsigned INT) Data-> indexcount; </P> <p> triangleindex * tmp_ind = new triangleindex [_ index_count]; <br/> If (_ indices) <br/> {<br/> memcpy (tmp_ind, _ indices, sizeof (unsigned INT) * prev_size ); <br/> Delete [] _ indices; <br/>}< br/> _ indices = tmp_ind; </P> <p> const unsigned int numtris = (unsigned INT) data-> indexcount/3; <br/> hardwareindexbuffersharedptr ibuf = data-> indexbuffer; <br/> const bool use32bitindexes = (ibuf-> GetType () = hardwareindexbuffer :: it_32bit); <br/> unsigned int index_offset = prev_size; </P> <p> If (use32bitindexes) <br/>{< br/> const unsigned int * pint = static_cast <unsigned int *> (ibuf-> lock (hardwarebuffer: hbl_read_only )); <br/> for (unsigned int K = 0; k <numtris; ++ K) <br/>{< br/> _ indices [index_offset ++] = offset + * pint ++; <br/> _ indices [index_offset ++] = offset + * pint ++; <br/> _ indices [index_offset ++] = offset + * pint ++; <br/>}< br/> ibuf-> unlock (); <br/>}< br/> else <br/> {<br/> const unsigned short * Pshort = static_cast <unsigned short *> (ibuf-> lock (hardwarebuffer :: hbl_read_only); <br/> for (unsigned int K = 0; k <numtris; ++ K) <br/>{< br/> _ indices [index_offset ++] = offset + static_cast <unsigned int> (* Pshort ++ ); <br/> _ indices [index_offset ++] = offset + static_cast <unsigned int> (* Pshort ++ ); <br/> _ indices [index_offset ++] = offset + static_cast <unsigned int> (* Pshort ++ ); <br/>}< br/> ibuf-> unlock (); <br/>}</P> <p>}