From 79eca25c945a535a7a0325999034bae17da92412 Mon Sep 17 00:00:00 2001 From: dan miller Date: Fri, 19 Oct 2007 05:15:33 +0000 Subject: resubmitting ode --- .../ode-0.9/ode/src/collision_trimesh_gimpact.cpp | 456 +++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 libraries/ode-0.9/ode/src/collision_trimesh_gimpact.cpp (limited to 'libraries/ode-0.9/ode/src/collision_trimesh_gimpact.cpp') diff --git a/libraries/ode-0.9/ode/src/collision_trimesh_gimpact.cpp b/libraries/ode-0.9/ode/src/collision_trimesh_gimpact.cpp new file mode 100644 index 0000000..229966b --- /dev/null +++ b/libraries/ode-0.9/ode/src/collision_trimesh_gimpact.cpp @@ -0,0 +1,456 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include +#include +#include +#include + +#if dTRIMESH_ENABLED + +#include "collision_util.h" +#define TRIMESH_INTERNAL +#include "collision_trimesh_internal.h" + +#if dTRIMESH_GIMPACT + +void dxTriMeshData::Preprocess(){ // stub +} + +dTriMeshDataID dGeomTriMeshDataCreate(){ + return new dxTriMeshData(); +} + +void dGeomTriMeshDataDestroy(dTriMeshDataID g){ + delete g; +} + +void dGeomTriMeshSetLastTransform( dxGeom* g, dMatrix4 last_trans ) { //stub +} + +dReal* dGeomTriMeshGetLastTransform( dxGeom* g ) { + return NULL; // stub +} + +void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) { //stub +} + +void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) { + dUASSERT(g, "argument not trimesh data"); + return NULL; // stub +} + +void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + dUASSERT(g, "argument not trimesh data"); + dIASSERT(Vertices); + dIASSERT(Indices); + + g->Build(Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, + Normals, + true); +} + + +void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride) +{ + dGeomTriMeshDataBuildSingle1(g, Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, (void*)NULL); +} + + +void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + dUASSERT(g, "argument not trimesh data"); + + g->Build(Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, + Normals, + false); +} + + +void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride) { + dGeomTriMeshDataBuildDouble1(g, Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, NULL); +} + + +void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const int* Indices, int IndexCount, + const int* Normals){ +#ifdef dSINGLE + dGeomTriMeshDataBuildSingle1(g, + Vertices, 4 * sizeof(dReal), VertexCount, + Indices, IndexCount, 3 * sizeof(unsigned int), + Normals); +#else + dGeomTriMeshDataBuildDouble1(g, Vertices, 4 * sizeof(dReal), VertexCount, + Indices, IndexCount, 3 * sizeof(unsigned int), + Normals); +#endif +} + + +void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const int* Indices, int IndexCount) { + dGeomTriMeshDataBuildSimple1(g, + Vertices, VertexCount, Indices, IndexCount, + (const int*)NULL); +} + +void dGeomTriMeshDataPreprocess(dTriMeshDataID g) +{ + dUASSERT(g, "argument not trimesh data"); + g->Preprocess(); +} + +void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen) +{ + dUASSERT(g, "argument not trimesh data"); + *buf = NULL; + *bufLen = 0; +} + +void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) +{ + dUASSERT(g, "argument not trimesh data"); +// g->UseFlags = buf; +} + + +// Trimesh + +dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1){ + type = dTriMeshClass; + + dGeomTriMeshSetData(this,Data); + + /* TC has speed/space 'issues' that don't make it a clear + win by default on spheres/boxes. */ + this->doSphereTC = true; + this->doBoxTC = true; + this->doCapsuleTC = true; + +} + +dxTriMesh::~dxTriMesh(){ + + //Terminate Trimesh + gim_trimesh_destroy(&m_collision_trimesh); +} + + +void dxTriMesh::ClearTCCache(){ + +} + + +int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]){ + return 1; +} + + +void dxTriMesh::computeAABB() +{ + //update trimesh transform + mat4f transform; + IDENTIFY_MATRIX_4X4(transform); + MakeMatrix(this, transform); + gim_trimesh_set_tranform(&m_collision_trimesh,transform); + + //Update trimesh boxes + gim_trimesh_update(&m_collision_trimesh); + + memcpy(aabb,&m_collision_trimesh.m_aabbset.m_global_bound,6*sizeof(GREAL)); +} + + +void dxTriMeshData::UpdateData() +{ +// BVTree.Refit(); +} + + +dGeomID dCreateTriMesh(dSpaceID space, + dTriMeshDataID Data, + dTriCallback* Callback, + dTriArrayCallback* ArrayCallback, + dTriRayCallback* RayCallback) +{ + dxTriMesh* Geom = new dxTriMesh(space, Data); + Geom->Callback = Callback; + Geom->ArrayCallback = ArrayCallback; + Geom->RayCallback = RayCallback; + + return Geom; +} + +void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + ((dxTriMesh*)g)->Callback = Callback; +} + +dTriCallback* dGeomTriMeshGetCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + return ((dxTriMesh*)g)->Callback; +} + +void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + ((dxTriMesh*)g)->ArrayCallback = ArrayCallback; +} + +dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + return ((dxTriMesh*)g)->ArrayCallback; +} + +void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + ((dxTriMesh*)g)->RayCallback = Callback; +} + +dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + return ((dxTriMesh*)g)->RayCallback; +} + +void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + dxTriMesh* mesh = (dxTriMesh*) g; + mesh->Data = Data; + // I changed my data -- I know nothing about my own AABB anymore. + ((dxTriMesh*)g)->gflags |= (GEOM_DIRTY|GEOM_AABB_BAD); + + // GIMPACT only supports stride 12, so we need to catch the error early. + dUASSERT + ( + Data->m_VertexStride == 3*sizeof(dReal) && Data->m_TriStride == 3*sizeof(int), + "Gimpact trimesh only supports a stride of 3 dReal/int\n" + "This means that you cannot use dGeomTriMeshDataBuildSimple() with Gimpact.\n" + "Change the stride, or use Opcode trimeshes instead.\n" + ); + + //Create trimesh + if ( Data->m_Vertices ) + gim_trimesh_create_from_data + ( + &mesh->m_collision_trimesh, // gimpact mesh + ( vec3f *)(&Data->m_Vertices[0]), // vertices + Data->m_VertexCount, // nr of verts + 0, // copy verts? + ( GUINT *)(&Data->m_Indices[0]), // indices + Data->m_TriangleCount*3, // nr of indices + 0, // copy indices? + 1 // transformed reply + ); +} + +dTriMeshDataID dGeomTriMeshGetData(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + return ((dxTriMesh*)g)->Data; +} + + + +void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + + switch (geomClass) + { + case dSphereClass: + ((dxTriMesh*)g)->doSphereTC = (1 == enable); + break; + case dBoxClass: + ((dxTriMesh*)g)->doBoxTC = (1 == enable); + break; + case dCapsuleClass: +// case dCCylinderClass: + ((dxTriMesh*)g)->doCapsuleTC = (1 == enable); + break; + } +} + +int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + + switch (geomClass) + { + case dSphereClass: + if (((dxTriMesh*)g)->doSphereTC) + return 1; + break; + case dBoxClass: + if (((dxTriMesh*)g)->doBoxTC) + return 1; + break; + case dCapsuleClass: + if (((dxTriMesh*)g)->doCapsuleTC) + return 1; + break; + } + return 0; +} + +void dGeomTriMeshClearTCCache(dGeomID g){ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + + dxTriMesh* Geom = (dxTriMesh*)g; + Geom->ClearTCCache(); +} + +/* + * returns the TriMeshDataID + */ +dTriMeshDataID +dGeomTriMeshGetTriMeshDataID(dGeomID g) +{ + dxTriMesh* Geom = (dxTriMesh*) g; + return Geom->Data; +} + +// Getting data +void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2) +{ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + + dxTriMesh* Geom = (dxTriMesh*)g; + gim_trimesh_locks_work_data(&Geom->m_collision_trimesh); + gim_trimesh_get_triangle_vertices(&Geom->m_collision_trimesh, Index, (*v0),(*v1),(*v2)); + gim_trimesh_unlocks_work_data(&Geom->m_collision_trimesh); + +} + +void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + + dxTriMesh* Geom = (dxTriMesh*)g; + dVector3 dv[3]; + gim_trimesh_locks_work_data(&Geom->m_collision_trimesh); + gim_trimesh_get_triangle_vertices(&Geom->m_collision_trimesh, Index, dv[0],dv[1],dv[2]); + GetPointFromBarycentric(dv, u, v, Out); + gim_trimesh_unlocks_work_data(&Geom->m_collision_trimesh); +} + +int dGeomTriMeshGetTriangleCount (dGeomID g) +{ + dxTriMesh* Geom = (dxTriMesh*)g; + return gim_trimesh_get_triangle_count(&Geom->m_collision_trimesh); +} + +void dGeomTriMeshDataUpdate(dTriMeshDataID g) { + dUASSERT(g, "argument not trimesh data"); + g->UpdateData(); +} + + +// +// GIMPACT TRIMESH-TRIMESH COLLIDER +// + +int dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (g2->type == dTriMeshClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh1 = (dxTriMesh*) g1; + dxTriMesh* TriMesh2 = (dxTriMesh*) g2; + //Create contact list + GDYNAMIC_ARRAY trimeshcontacts; + GIM_CREATE_CONTACT_LIST(trimeshcontacts); + + //Collide trimeshes + gim_trimesh_trimesh_collision(&TriMesh1->m_collision_trimesh,&TriMesh2->m_collision_trimesh,&trimeshcontacts); + + if(trimeshcontacts.m_size == 0) + { + GIM_DYNARRAY_DESTROY(trimeshcontacts); + return 0; + } + + GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); + + + unsigned contactcount = trimeshcontacts.m_size; + unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK); + if (contactcount > maxcontacts) + { + contactcount = maxcontacts; + } + + dContactGeom* pcontact; + unsigned i; + + for (i=0;ipos[0] = ptrimeshcontacts->m_point[0]; + pcontact->pos[1] = ptrimeshcontacts->m_point[1]; + pcontact->pos[2] = ptrimeshcontacts->m_point[2]; + pcontact->pos[3] = 1.0f; + + pcontact->normal[0] = ptrimeshcontacts->m_normal[0]; + pcontact->normal[1] = ptrimeshcontacts->m_normal[1]; + pcontact->normal[2] = ptrimeshcontacts->m_normal[2]; + pcontact->normal[3] = 0; + + pcontact->depth = ptrimeshcontacts->m_depth; + pcontact->g1 = g1; + pcontact->g2 = g2; + + ptrimeshcontacts++; + } + + GIM_DYNARRAY_DESTROY(trimeshcontacts); + + return (int)contactcount; +} + +#endif // dTRIMESH_GIMPACT +#endif // dTRIMESH_ENABLED -- cgit v1.1