From 0fc46fc9590912bf6925c899edd02d7a2cdf5f79 Mon Sep 17 00:00:00 2001 From: dan miller Date: Fri, 19 Oct 2007 04:28:53 +0000 Subject: adding ode source to /libraries --- "libraries/ode-0.9\\/contrib/dRay/Include/dRay.h" | 15 + "libraries/ode-0.9\\/contrib/dRay/README.txt" | 16 + .../ode-0.9\\/contrib/dRay/Test/test_ray.cpp" | 1372 ++++++++++++++++++++ "libraries/ode-0.9\\/contrib/dRay/dRay.cpp" | 119 ++ "libraries/ode-0.9\\/contrib/dRay/dRay_Box.cpp" | 134 ++ .../ode-0.9\\/contrib/dRay/dRay_CCylinder.cpp" | 199 +++ "libraries/ode-0.9\\/contrib/dRay/dRay_Plane.cpp" | 35 + "libraries/ode-0.9\\/contrib/dRay/dRay_Sphere.cpp" | 95 ++ "libraries/ode-0.9\\/contrib/dRay/dxRay.h" | 32 + 9 files changed, 2017 insertions(+) create mode 100755 "libraries/ode-0.9\\/contrib/dRay/Include/dRay.h" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/README.txt" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/Test/test_ray.cpp" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/dRay.cpp" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/dRay_Box.cpp" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/dRay_CCylinder.cpp" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/dRay_Plane.cpp" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/dRay_Sphere.cpp" create mode 100755 "libraries/ode-0.9\\/contrib/dRay/dxRay.h" (limited to 'libraries/ode-0.9\/contrib/dRay') diff --git "a/libraries/ode-0.9\\/contrib/dRay/Include/dRay.h" "b/libraries/ode-0.9\\/contrib/dRay/Include/dRay.h" new file mode 100755 index 0000000..f6caea8 --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/Include/dRay.h" @@ -0,0 +1,15 @@ +#include "ode\ode.h" + +/* Class ID */ +extern int dRayClass; + +/* Creates a ray */ +dxGeom* dGeomCreateRay(dSpaceID space, dReal Length); + +/* Set/Get length */ +void dGeomRaySetLength(dxGeom* g, dReal Length); +dReal dGeomRayGetLength(dxGeom* g); + +/* Utility function to override the ray's pos + rot */ +void dGeomRaySet(dxGeom* g, dVector3 Origin, dVector3 Direction); +void dGeomRayGet(dxGeom* g, dVector3 Origin, dVector3 Direction); diff --git "a/libraries/ode-0.9\\/contrib/dRay/README.txt" "b/libraries/ode-0.9\\/contrib/dRay/README.txt" new file mode 100755 index 0000000..8997208 --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/README.txt" @@ -0,0 +1,16 @@ +From: "Erwin de Vries" +To: +Subject: [ODE] dRay class +Date: Thu, 25 Jul 2002 13:05:28 +0200 + +Yesterday and today i've written a dRay class. It interacts with dPlane, +dSphere, dBox and dCCylinder. It does not generate full contact information. +It only generates the pos member. I dont think its useful to anyone to go +through hoops and find a reasonable normal and penetration depth, as i dont +think anyone will want to use it for dynamics. Just for CD. + +It should compile in single and double precision mode, and should be +platform independant. I hope. + +The next Tri-Collider release using Opcode 1.1 will also implement a ray +collision function along with some other not too interesting improvements. diff --git "a/libraries/ode-0.9\\/contrib/dRay/Test/test_ray.cpp" "b/libraries/ode-0.9\\/contrib/dRay/Test/test_ray.cpp" new file mode 100755 index 0000000..faa8b14 --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/Test/test_ray.cpp" @@ -0,0 +1,1372 @@ +/************************************************************************* + + + * * + + + * Open Dynamics Engine, Copyright (C) 2001,2002 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 + + + + + +#ifdef _MSC_VER + + +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints + + +#endif + + + + + +// select correct drawing functions + + + + + +#ifdef dDOUBLE + + +#define dsDrawBox dsDrawBoxD + + +#define dsDrawSphere dsDrawSphereD + + +#define dsDrawCylinder dsDrawCylinderD + + +#define dsDrawCappedCylinder dsDrawCappedCylinderD + + +#endif + + + + + + + + +// some constants + + + + + +#define NUM 20 // max number of objects + + +#define DENSITY (5.0) // density of all objects + + +#define GPB 3 // maximum number of geometries per body + + + + + + + + +// dynamics and collision objects + + + + + +struct MyObject { + + + dBodyID body; // the body + + + dGeomID geom[GPB]; // geometries representing this body + + +}; + + + + + +static int num=0; // number of objects in simulation + + +static int nextobj=0; // next object to recycle if num==NUM + + +static dWorldID world; + + +static dSpaceID space; + + +static MyObject obj[NUM]; + + +static dJointGroupID contactgroup; + + +static int selected = -1; // selected object + + + + + +static dGeomID* Rays; + + +static int RayCount; + + + + + +// this is called by dSpaceCollide when two objects in space are + + +// potentially colliding. + + + + + +static void nearCallback (void *data, dGeomID o1, dGeomID o2) + + +{ + + + int i; + + + // if (o1->body && o2->body) return; + + + + + + // exit without doing anything if the two bodies are connected by a joint + + + dBodyID b1 = dGeomGetBody(o1); + + + dBodyID b2 = dGeomGetBody(o2); + + + if (b1 && b2 && dAreConnected (b1,b2)) return; + + + + + + dContact contact[32]; // up to 3 contacts per box + + + for (i=0; i<32; i++) { + + + contact[i].surface.mode = dContactBounce; //dContactMu2; + + + contact[i].surface.mu = dInfinity; + + + contact[i].surface.mu2 = 0; + + + contact[i].surface.bounce = 0.5; + + + contact[i].surface.bounce_vel = 0.1; + + + } + + + if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { + + + dMatrix3 RI; + + + dRSetIdentity (RI); + + + const dReal ss[3] = {0.02,0.02,0.02}; + + + for (i=0; i= 'A' && c <= 'Z') return c - ('a'-'A'); + + + else return c; + + +} + + + + + + + + +// called when a key pressed + + + + + +static void command (int cmd) + + +{ + + + int i,j,k; + + + dReal sides[3]; + + + dMass m; + + + + + + cmd = locase (cmd); + + + if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x') { + + + if (num < NUM) { + + + i = num; + + + num++; + + + } + + + else { + + + i = nextobj; + + + nextobj++; + + + if (nextobj >= num) nextobj = 0; + + + + + + // destroy the body and geoms for slot i + + + dBodyDestroy (obj[i].body); + + + for (k=0; k < GPB; k++) { + + + if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); + + + } + + + memset (&obj[i],0,sizeof(obj[i])); + + + } + + + + + + obj[i].body = dBodyCreate (world); + + + for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; + + + + + + dBodySetPosition (obj[i].body, + + + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+1); + + + dMatrix3 R; + + + dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + + + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + + + dBodySetRotation (obj[i].body,R); + + + dBodySetData (obj[i].body,(void*) i); + + + + + + if (cmd == 'b') { + + + dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); + + + obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); + + + } + + + else if (cmd == 'c') { + + + sides[0] *= 0.5; + + + dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); + + + obj[i].geom[0] = dCreateCCylinder (space,sides[0],sides[1]); + + + } + + + else if (cmd == 's') { + + + sides[0] *= 0.5; + + + dMassSetSphere (&m,DENSITY,sides[0]); + + + obj[i].geom[0] = dCreateSphere (space,sides[0]); + + + } + + + else if (cmd == 'x') { + + + dGeomID g2[GPB]; // encapsulated geometries + + + dReal dpos[GPB][3]; // delta-positions for encapsulated geometries + + + + + + // start accumulating masses for the encapsulated geometries + + + dMass m2; + + + dMassSetZero (&m); + + + + + + // set random delta positions + + + for (j=0; j= num) selected = 0; + + + if (selected < 0) selected = 0; + + + } + + + else if (cmd == 'd' && selected >= 0 && selected < num) { + + + dBodyDisable (obj[selected].body); + + + } + + + else if (cmd == 'e' && selected >= 0 && selected < num) { + + + dBodyEnable (obj[selected].body); + + + } + + +} + + + + + + + + +// draw a geom + + + + + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R) + + +{ + + + if (!g) return; + + + if (!pos) pos = dGeomGetPosition (g); + + + if (!R) R = dGeomGetRotation (g); + + + + + + int type = dGeomGetClass (g); + + + if (type == dBoxClass) { + + + dVector3 sides; + + + dGeomBoxGetLengths (g,sides); + + + dsDrawBox (pos,R,sides); + + + } + + + else if (type == dSphereClass) { + + + dsDrawSphere (pos,R,dGeomSphereGetRadius (g)); + + + } + + + else if (type == dCCylinderClass) { + + + dReal radius,length; + + + dGeomCCylinderGetParams (g,&radius,&length); + + + dsDrawCappedCylinder (pos,R,length,radius); + + + } + + + else if (type == dGeomTransformClass) { + + + dGeomID g2 = dGeomTransformGetGeom (g); + + + const dReal *pos2 = dGeomGetPosition (g2); + + + const dReal *R2 = dGeomGetRotation (g2); + + + dVector3 actual_pos; + + + dMatrix3 actual_R; + + + dMULTIPLY0_331 (actual_pos,R,pos2); + + + actual_pos[0] += pos[0]; + + + actual_pos[1] += pos[1]; + + + actual_pos[2] += pos[2]; + + + dMULTIPLY0_333 (actual_R,R,R2); + + + drawGeom (g2,actual_pos,actual_R); + + + } + + +} + + + + + + + + +// simulation loop + + + + + +static void simLoop (int pause) + + +{ + + + dsSetColor (0,0,2); + + + dSpaceCollide (space,0,&nearCallback); + + + if (!pause) dWorldStep (world,0.05); + + + + + + // remove all contact joints + + + dJointGroupEmpty (contactgroup); + + + + + + dsSetColor (1,1,0); + + + dsSetTexture (DS_WOOD); + + + for (int i=0; iLength = Length; +} + +dReal dGeomRayGetLength(dxGeom* g){ + return ((dxRay*)dGeomGetClassData(g))->Length; +} + +void dGeomRaySet(dxGeom* g, dVector3 Origin, dVector3 Direction){ + dGeomSetPosition(g, Origin[0], Origin[1], Origin[2]); + + dVector3 Up, Right; + dPlaneSpace(Direction, Up, Right); + + Origin[3] = Up[3] = Right[3] = REAL(0.0); + + dMatrix3 Rotation; + Rotation[0 * 4 + 0] = Right[0]; + Rotation[1 * 4 + 0] = Right[1]; + Rotation[2 * 4 + 0] = Right[2]; + Rotation[3 * 4 + 0] = Right[3]; + + Rotation[0 * 4 + 1] = Up[0]; + Rotation[1 * 4 + 1] = Up[1]; + Rotation[2 * 4 + 1] = Up[2]; + Rotation[3 * 4 + 1] = Up[3]; + + Rotation[0 * 4 + 2] = Direction[0]; + Rotation[1 * 4 + 2] = Direction[1]; + Rotation[2 * 4 + 2] = Direction[2]; + Rotation[3 * 4 + 2] = Direction[3]; + + dGeomSetRotation(g, Rotation); +} + +void dGeomRayGet(dxGeom* g, dVector3 Origin, dVector3 Direction){ + const dReal* Position = dGeomGetPosition(g); + Origin[0] = Position[0]; + Origin[1] = Position[1]; + Origin[2] = Position[2]; + Origin[3] = Position[3]; + + const dReal* Rotation = dGeomGetRotation(g); + Direction[0] = Rotation[0 * 4 + 2]; + Direction[1] = Rotation[1 * 4 + 2]; + Direction[2] = Rotation[2 * 4 + 2]; + Direction[3] = Rotation[3 * 4 + 2]; +} \ No newline at end of file diff --git "a/libraries/ode-0.9\\/contrib/dRay/dRay_Box.cpp" "b/libraries/ode-0.9\\/contrib/dRay/dRay_Box.cpp" new file mode 100755 index 0000000..d2a0d9c --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/dRay_Box.cpp" @@ -0,0 +1,134 @@ +// Ripped from Magic Software + +#include "Include\dRay.h" +#include "dxRay.h" + +bool Clip(dReal Denom, dReal Numer, dReal& T0, dReal& T1){ + // Return value is 'true' if line segment intersects the current test + // plane. Otherwise 'false' is returned in which case the line segment + // is entirely clipped. + + if (Denom > REAL(0.0)){ + if (Numer > Denom * T1){ + return false; + } + + if (Numer > Denom * T0){ + T0 = Numer / Denom; + } + return true; + } + else if (Denom < REAL(0.0)){ + if (Numer > Denom * T0){ + return false; + } + + if (Numer > Denom * T1){ + T1 = Numer / Denom; + } + return true; + } + else return Numer <= REAL(0.0); +} + +bool FindIntersection(const dVector3 Origin, const dVector3 Direction, const dVector3 Extents, dReal& T0, dReal& T1){ + dReal SaveT0 = T0; + dReal SaveT1 = T1; + + bool NotEntirelyClipped = + Clip(+Direction[0], -Origin[0] - Extents[0], T0, T1) && + Clip(-Direction[0], +Origin[0] - Extents[0], T0, T1) && + Clip(+Direction[1], -Origin[1] - Extents[1], T0, T1) && + Clip(-Direction[1], +Origin[1] - Extents[1], T0, T1) && + Clip(+Direction[2], -Origin[2] - Extents[2], T0, T1) && + Clip(-Direction[2], +Origin[2] - Extents[2], T0, T1); + + return NotEntirelyClipped && (T0 != SaveT0 || T1 != SaveT1); +} + +int dCollideBR(dxGeom* RayGeom, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride){ + const dVector3& Position = *(const dVector3*)dGeomGetPosition(BoxGeom); + const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(BoxGeom); + dVector3 Extents; + dGeomBoxGetLengths(BoxGeom, Extents); + Extents[0] /= 2; + Extents[1] /= 2; + Extents[2] /= 2; + Extents[3] /= 2; + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + dReal Length = dGeomRayGetLength(RayGeom); + + dVector3 Diff; + Diff[0] = Origin[0] - Position[0]; + Diff[1] = Origin[1] - Position[1]; + Diff[2] = Origin[2] - Position[2]; + Diff[3] = Origin[3] - Position[3]; + + Direction[0] *= Length; + Direction[1] *= Length; + Direction[2] *= Length; + Direction[3] *= Length; + + dVector3 Rot[3]; + Decompose(Rotation, Rot); + + dVector3 TransOrigin; + TransOrigin[0] = dDOT(Diff, Rot[0]); + TransOrigin[1] = dDOT(Diff, Rot[1]); + TransOrigin[2] = dDOT(Diff, Rot[2]); + TransOrigin[3] = REAL(0.0); + + dVector3 TransDirection; + TransDirection[0] = dDOT(Direction, Rot[0]); + TransDirection[1] = dDOT(Direction, Rot[1]); + TransDirection[2] = dDOT(Direction, Rot[2]); + TransDirection[3] = REAL(0.0); + + dReal T[2]; + T[0] = 0.0f; + T[1] = dInfinity; + + bool Intersect = FindIntersection(TransOrigin, TransDirection, Extents, T[0], T[1]); + + if (Intersect){ + if (T[0] > REAL(0.0)){ + dContactGeom* Contact0 = CONTACT(Flags, Contacts, 0, Stride); + Contact0->pos[0] = Origin[0] + T[0] * Direction[0]; + Contact0->pos[1] = Origin[1] + T[0] * Direction[1]; + Contact0->pos[2] = Origin[2] + T[0] * Direction[2]; + Contact0->pos[3] = Origin[3] + T[0] * Direction[3]; + //Contact0->normal = 0; + Contact0->depth = 0.0f; + Contact0->g1 = RayGeom; + Contact0->g2 = BoxGeom; + + dContactGeom* Contact1 = CONTACT(Flags, Contacts, 1, Stride); + Contact1->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact1->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact1->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact1->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact1->normal = 0; + Contact1->depth = 0.0f; + Contact1->g1 = RayGeom; + Contact1->g2 = BoxGeom; + + return 2; + } + else{ + dContactGeom* Contact = CONTACT(Flags, Contacts, 0, Stride); + Contact->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = BoxGeom; + + return 1; + } + } + else return 0; +} \ No newline at end of file diff --git "a/libraries/ode-0.9\\/contrib/dRay/dRay_CCylinder.cpp" "b/libraries/ode-0.9\\/contrib/dRay/dRay_CCylinder.cpp" new file mode 100755 index 0000000..b9ea0c0 --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/dRay_CCylinder.cpp" @@ -0,0 +1,199 @@ +// Ripped from Magic Software + +#include "Include\dRay.h" +#include "dxRay.h" + +int Find(const dVector3 Origin, dVector3 Direction, dReal Length, const dVector3 CCPos, const dMatrix3 CCRot, dReal CCRadius, dReal CCLength, dReal T[2]){ + dVector3 U, V, W; + Decompose(CCRot, U, V, W); + + dVector3 CCOrigin; + CCOrigin[0] = CCPos[0] - (W[0] * CCLength / 2); + CCOrigin[1] = CCPos[1] - (W[1] * CCLength / 2); + CCOrigin[2] = CCPos[2] - (W[2] * CCLength / 2); + CCOrigin[3] = CCPos[3] - (W[3] * CCLength / 2); + + dVector3 D; + D[0] = dDOT(U, Direction); + D[1] = dDOT(V, Direction); + D[2] = dDOT(W, Direction); + + dReal DMag = Length; + dReal InvDMag = REAL(1.0) / DMag; + + dVector3 Diff; + Diff[0] = Origin[0] - CCOrigin[0]; + Diff[1] = Origin[1] - CCOrigin[1]; + Diff[2] = Origin[2] - CCOrigin[2]; + Diff[3] = Origin[3] - CCOrigin[3]; + + dVector3 P; + P[0] = dDOT(U, Diff); + P[1] = dDOT(V, Diff); + P[2] = dDOT(W, Diff); + + dReal CCRadiusSq = CCRadius * CCRadius; + + dReal Epsilon = 1e-12f; + + if (dFabs(D[2]) >= REAL(1.0) - Epsilon){ // line is parallel to capsule axis + dReal Discr = CCRadiusSq - P[0] * P[0] - P[1] * P[1]; + + if (Discr >= REAL(0.0)){ + dReal Root = dSqrt(Discr); + T[0] = (-P[2] + Root) * InvDMag; + T[1] = (CCLength - P[2] + Root) * InvDMag; + return 2; + } + else return 0; + } + + // test intersection with infinite cylinder + dReal A = D[0] * D[0] + D[1] * D[1]; + dReal B = P[0] * D[0] + P[1] * D[1]; + dReal C = P[0] * P[0] + P[1] * P[1] - CCRadiusSq; + dReal Discr = B * B - A * C; + if (Discr < REAL(0.0)){ // line does not intersect infinite cylinder + return 0; + } + + int Count = 0; + + if (Discr > REAL(0.0)){ // line intersects infinite cylinder in two places + dReal Root = dSqrt(Discr); + dReal Inv = REAL(1.0) / A; + + dReal TTemp = (-B - Root) * Inv; + + dReal Tmp = P[2] + TTemp * D[2]; + if (REAL(0.0) <= Tmp && Tmp <= CCLength){ + T[Count++] = TTemp * InvDMag; + } + + + TTemp = (-B + Root) * Inv; + Tmp = P[2] + TTemp * D[2]; + if (REAL(0.0) <= Tmp && Tmp <= CCLength){ + T[Count++] = TTemp * InvDMag; + } + + if (Count == 2){ // line intersects capsule wall in two places + return 2; + } + } + else{ // line is tangent to infinite cylinder + dReal TTemp = -B / A; + dReal Tmp = P[2] + TTemp * D[2]; + if (REAL(0.0) <= Tmp && Tmp <= CCLength){ + T[0] = TTemp * InvDMag; + return 1; + } + } + + // test intersection with bottom hemisphere + // fA = 1 + B += P[2] * D[2]; + C += P[2] * P[2]; + Discr = B * B - C; + if (Discr > REAL(0.0)){ + dReal Root = dSqrt(Discr); + dReal TTemp = -B - Root; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp <= REAL(0.0)){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + + TTemp = -B + Root; + Tmp = P[2] + TTemp * D[2]; + if (Tmp <= REAL(0.0)){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + else if (Discr == REAL(0.0)){ + dReal TTemp = -B; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp <= REAL(0.0)){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + + // test intersection with top hemisphere + // fA = 1 + B -= D[2] * CCLength; + C += CCLength * (CCLength - REAL(2.0) * P[2]); + + Discr = B * B - C; + if (Discr > REAL(0.0)){ + dReal Root = dSqrt(Discr); + dReal TTemp = -B - Root; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp >= CCLength){ + + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + + TTemp = -B + Root; + Tmp = P[2] + TTemp * D[2]; + if (Tmp >= CCLength){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + else if (Discr == REAL(0.0)){ + dReal TTemp = -B; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp >= CCLength){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + return Count; +} + +int dCollideCCR(dxGeom* RayGeom, dxGeom* CCGeom, int Flags, dContactGeom* Contacts, int Stride){ + const dVector3& CCPos = *(const dVector3*)dGeomGetPosition(CCGeom); + const dMatrix3& CCRot = *(const dMatrix3*)dGeomGetRotation(CCGeom); + + dReal CCRadius, CCLength; + dGeomCCylinderGetParams(CCGeom, &CCRadius, &CCLength); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + dReal Length = dGeomRayGetLength(RayGeom); + + dReal T[2]; + int Count = Find(Origin, Direction, Length, CCPos, CCRot, CCRadius, CCLength, T); + int ContactCount = 0; + for (int i = 0; i < Count; i++){ + if (T[i] >= 0.0){ + dContactGeom* Contact = CONTACT(Flags, Contacts, ContactCount, Stride); + Contact->pos[0] = Origin[0] + T[i] * Direction[0] * Length; + Contact->pos[1] = Origin[1] + T[i] * Direction[1] * Length; + Contact->pos[2] = Origin[2] + T[i] * Direction[2] * Length; + Contact->pos[3] = Origin[3] + T[i] * Direction[3] * Length; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = CCGeom; + + ContactCount++; + } + } + return ContactCount; +} \ No newline at end of file diff --git "a/libraries/ode-0.9\\/contrib/dRay/dRay_Plane.cpp" "b/libraries/ode-0.9\\/contrib/dRay/dRay_Plane.cpp" new file mode 100755 index 0000000..cf03c5b --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/dRay_Plane.cpp" @@ -0,0 +1,35 @@ +// Ripped from Paul Bourke + +#include "Include\dRay.h" +#include "dxRay.h" + +int dCollidePR(dxGeom* RayGeom, dxGeom* PlaneGeom, int Flags, dContactGeom* Contact, int Stride){ + dVector3 Plane; + dGeomPlaneGetParams(PlaneGeom, Plane); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + + dReal Length = dGeomRayGetLength(RayGeom); + + dReal Denom = Plane[0] * Direction[0] + Plane[1] * Direction[1] + Plane[2] * Direction[2]; + if (dFabs(Denom) < 0.00001f){ + return 0; // Ray never hits + } + + float T = -(Plane[3] + Plane[0] * Origin[0] + Plane[1] * Origin[1] + Plane[2] * Origin[2]) / Denom; + + if (T < 0 || T > Length){ + return 0; // Ray hits but not within boundaries + } + + Contact->pos[0] = Origin[0] + T * Direction[0]; + Contact->pos[1] = Origin[1] + T * Direction[1]; + Contact->pos[2] = Origin[2] + T * Direction[2]; + Contact->pos[3] = REAL(0.0); + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = PlaneGeom; + return 1; +} \ No newline at end of file diff --git "a/libraries/ode-0.9\\/contrib/dRay/dRay_Sphere.cpp" "b/libraries/ode-0.9\\/contrib/dRay/dRay_Sphere.cpp" new file mode 100755 index 0000000..8e1ac39 --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/dRay_Sphere.cpp" @@ -0,0 +1,95 @@ +// Ripped from Magic Software + +#include "Include\dRay.h" +#include "dxRay.h" + +int dCollideSR(dxGeom* RayGeom, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride){ + const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom); + dReal Radius = dGeomSphereGetRadius(SphereGeom); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + dReal Length = dGeomRayGetLength(RayGeom); + + dVector3 Diff; + Diff[0] = Origin[0] - Position[0]; + Diff[1] = Origin[1] - Position[1]; + Diff[2] = Origin[2] - Position[2]; + Diff[3] = Origin[3] - Position[3]; + + Direction[0] *= Length; + Direction[1] *= Length; + Direction[2] *= Length; + Direction[3] *= Length; + + dReal A = Length * Length; + dReal B = dDOT(Diff, Direction); + dReal C = dDOT(Diff, Diff) - (Radius * Radius); + + dReal Discr = B * B - A * C; + if (Discr < REAL(0.0)){ + return 0; + } + else if (Discr > REAL(0.0)){ + dReal T[2]; + dReal Root = dSqrt(Discr); + dReal InvA = REAL(1.0) / A; + T[0] = (-B - Root) * InvA; + T[1] = (-B + Root) * InvA; + + if (T[0] >= REAL(0.0)){ + dContactGeom* Contact0 = CONTACT(Flags, Contacts, 0, Stride); + Contact0->pos[0] = Origin[0] + T[0] * Direction[0]; + Contact0->pos[1] = Origin[1] + T[0] * Direction[1]; + Contact0->pos[2] = Origin[2] + T[0] * Direction[2]; + Contact0->pos[3] = Origin[3] + T[0] * Direction[3]; + //Contact0->normal = 0; + Contact0->depth = 0.0f; + Contact0->g1 = RayGeom; + Contact0->g2 = SphereGeom; + + dContactGeom* Contact1 = CONTACT(Flags, Contacts, 1, Stride); + Contact1->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact1->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact1->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact1->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact1->normal = 0; + Contact1->depth = 0.0f; + Contact1->g1 = RayGeom; + Contact1->g2 = SphereGeom; + + return 2; + } + else if (T[1] >= REAL(0.0)){ + dContactGeom* Contact = CONTACT(Flags, Contacts, 1, Stride); + Contact->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = SphereGeom; + + return 1; + } + else return 0; + } + else{ + dReal T; + T = -B / A; + if (T >= REAL(0.0)){ + dContactGeom* Contact = CONTACT(Flags, Contacts, 0, Stride); + Contact->pos[0] = Origin[0] + T * Direction[0]; + Contact->pos[1] = Origin[1] + T * Direction[1]; + Contact->pos[2] = Origin[2] + T * Direction[2]; + Contact->pos[3] = Origin[3] + T * Direction[3]; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = SphereGeom; + return 1; + } + else return 0; + } +} \ No newline at end of file diff --git "a/libraries/ode-0.9\\/contrib/dRay/dxRay.h" "b/libraries/ode-0.9\\/contrib/dRay/dxRay.h" new file mode 100755 index 0000000..0fd1d2d --- /dev/null +++ "b/libraries/ode-0.9\\/contrib/dRay/dxRay.h" @@ -0,0 +1,32 @@ +struct dxRay{ + dReal Length; +}; + +inline void Decompose(const dMatrix3 Matrix, dVector3 Right, dVector3 Up, dVector3 Direction){ + Right[0] = Matrix[0 * 4 + 0]; + Right[1] = Matrix[1 * 4 + 0]; + Right[2] = Matrix[2 * 4 + 0]; + Right[3] = Matrix[3 * 4 + 0]; + Up[0] = Matrix[0 * 4 + 1]; + Up[1] = Matrix[1 * 4 + 1]; + Up[2] = Matrix[2 * 4 + 1]; + Up[3] = Matrix[3 * 4 + 1]; + Direction[0] = Matrix[0 * 4 + 2]; + Direction[1] = Matrix[1 * 4 + 2]; + Direction[2] = Matrix[2 * 4 + 2]; + Direction[3] = Matrix[3 * 4 + 2]; +} + +inline void Decompose(const dMatrix3 Matrix, dVector3 Vectors[3]){ + Decompose(Matrix, Vectors[0], Vectors[1], Vectors[2]); +} + +inline dContactGeom* CONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){ + dIASSERT(Index >= 0 && Index < (Flags & 0x0ffff)); + return ((dContactGeom*)(((char*)Contacts) + (Index * Stride))); +} + +int dCollidePR(dxGeom* RayGeom, dxGeom* PlaneGeom, int Flags, dContactGeom* Contacts, int Stride); +int dCollideSR(dxGeom* RayGeom, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride); +int dCollideBR(dxGeom* RayGeom, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride); +int dCollideCCR(dxGeom* RayGeom, dxGeom* CCylinderGeom, int Flags, dContactGeom* Contacts, int Stride); \ No newline at end of file -- cgit v1.1