[ODE] visibility detemination?
Erwin de Vries
erwin at vo.com
Mon May 5 01:26:02 2003
This is a multi-part message in MIME format.
------=_NextPart_000_002E_01C312F0.CBAF4C20
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hi,
Here is a little example on how i did it. It does not compile for you
because it is based on my own collision system, but it is very similar to
the ODE version, so i think you'll be able to understand it. I never used
this and i'm not sure it even works, but it might just same you some work.
Regards,
Erwin
----- Original Message -----
From: "Clint Brewer" <clint@haptek.com>
Cc: <ode@q12.org>
Sent: Monday, May 05, 2003 08:24
Subject: Re: [ODE] visibility detemination?
> Hi All,
> well after a good bit of time away, I'm finally getting a chance to work
> on this again.
> I just spent a good day or so planning it out and reading over the docs,
> I think it's going to be easily do-able as we discussed before, just
> having a special callback function for visibility determination that
> gets called when you collide a frustum with a dSpace
>
> I'll create a reusable frustum geometry type so that others can use it
> for the same purpose if they want.
>
>
> gl : not sure if you are still arround or not, I'll try out your
> terrain collision geometry soon too. Have you worked on it anymore?
>
>
> best,
> clint
>
>
>
>
> skjold@cistron.nl wrote:
>
> >>I could be off my rocker here, but doesn't ODE do CD at two levels of
> >>precision? Like, dSpaceCollide looks for potential collisions, and then
> >>the callback function uses dCollide to get penetration
> >>points/normals/depths, etc?
> >>
> >>Would the "coarse" CD of dSpaceCollide might make a good FOV test, if a
> >>frustum geometry class were added?
> >>
> >>
> >
> >Yes, that was the general idea being discussed: To take advantage of the
callback used by dSpaceCollide in determining potential visibility, but not
to actually call dCollide for it.
> >_______________________________________________
> >ODE mailing list
> >ODE@q12.org
> >http://q12.org/mailman/listinfo/ode
> >
> >
> >
>
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode
>
>
------=_NextPart_000_002E_01C312F0.CBAF4C20
Content-Type: application/octet-stream;
name="dFrustum.cpp"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="dFrustum.cpp"
#include "Include/dGeom.h"
#include "dxFrustum.h"
#include <ode/odemath.h>
#include "dxGeom.h"
SHAREDLIBEXPORT int dcFrustumClass =3D -1;
int dcCollideF(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* =
Contacts, int Stride){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g1);
// Allocate a temporary array
dArray<dVector4> Planes;
Planes.swap((dArray<dVector4>&)Data->Planes);
g1->_class->num =3D &dcPlaneClass; // Trick the collision detection =
into thinking 'this' is a plane.
int PlaneCount =3D Planes.size();
int Index;
for (Index =3D 0; Index < PlaneCount; Index++){
// Copy the plane to the temporary position
Data->Plane[0] =3D Planes[Index][0];
Data->Plane[1] =3D Planes[Index][1];
Data->Plane[2] =3D Planes[Index][2];
Data->Plane[3] =3D Planes[Index][3];
if (!dCollide(g1, g2, Flags, Contacts, Stride)){
break;
}
}
// Cleanup
g1->_class->num =3D &dcFrustumClass; // Reset the trick
Planes.swap((dArray<dVector4>&)Data->Planes); // Make sure to =
'remember' the old data
Planes.constructor();
// Did we early exit?
return Index =3D=3D PlaneCount;
}
static dcColliderFn* dxFrustumColliderFn(int num){
return dcCollideF;
}
static void dxFrustumAABB(dxGeom* g, dReal AABB[6]){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
AABB[0] =3D dInfinity;
AABB[1] =3D -dInfinity;
AABB[2] =3D dInfinity;
AABB[3] =3D -dInfinity;
AABB[4] =3D dInfinity;
AABB[5] =3D -dInfinity;
dArray<dVector4>& Planes =3D (dArray<dVector4>&)Data->Planes;
// This could be optimized.
// The frustum is computed out of the first 6 planes. All the other =
planes
// contribute to the culling, but not to the volume of the AABB.
for (int i =3D 0; i < 6; i++){
const dVector4& p0 =3D Planes[(i + 0) % 6];
const dVector4& p1 =3D Planes[(i + 1) % 6];
const dVector4& p2 =3D Planes[(i + 2) % 6];
dReal N00 =3D dDOT(p0, p0);
dReal N01 =3D dDOT(p0, p1);
dReal N11 =3D dDOT(p1, p1);
dReal Det =3D N00 * N11 - N01 * N01;
=09
dReal InvDet =3D REAL(1.0) / Det;
dReal C0 =3D (N11 * p0[3] - N01 * p1[3]) * InvDet;
dReal C1 =3D (N00 * p1[3] - N01 * p0[3]) * InvDet;
dVector3 Origin;
Origin[0] =3D C0 * p0[0] + C1 * p1[0];
Origin[1] =3D C0 * p0[1] + C1 * p1[1];
Origin[2] =3D C0 * p0[2] + C1 * p1[2];
dVector3 Direction;
dCROSS(Direction, =3D, p0, p1);
dReal Denom =3D dDOT(p2, Direction);
=09
float T =3D -(dDOT(p2, Origin) + p2[3]) / Denom;
for (int j =3D 0; j < 3; j++){
dReal& Min =3D AABB[j * 2 + 0];
dReal& Max =3D AABB[j * 2 + 1];
dReal f =3D Origin[j] + T * Direction[j];
if (f < Min){
Min =3D f;
}
if (f > Max){
Max =3D f;
}
}
}
}
dGeomID dcCreateFrustum (dSpaceID space, const dVector4* Planes, int =
PlaneCount){
if (dcFrustumClass =3D=3D -1) {
dcGeomClass c;
c.bytes =3D sizeof (dxFrustum);
c.collider =3D &dxFrustumColliderFn;
c.aabb =3D &dxFrustumAABB;
c.aabb_test =3D 0;
c.dtor =3D 0;
c.lock =3D 0;
c.unlock =3D 0;
c.moved =3D 0;
dcCreateGeomClass (&c, &dcFrustumClass);
}
=09
dxGeom *g =3D dcCreateGeom (dcFrustumClass);
=09
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
((dArray<dVector4>&)Data->Planes).constructor();
dcGeomFrustumSetPlanes(g, Planes, PlaneCount);
if (space) dcSpaceAdd (space,g);
=09
return g;
}
void dcGeomFrustumSetPlanes(dGeomID g, const dVector4* Planes, int =
PlaneCount){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
dArray<dVector4>& LocalPlanes =3D (dArray<dVector4>&)Data->Planes;
LocalPlanes.setSize(PlaneCount);
memcpy(LocalPlanes.data(), Planes, PlaneCount * sizeof(dVector4));
g->flags |=3D dxGeomMoved;
}
const dVector4* dcGeomFrustumGetPlanes(dGeomID g){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
=09
dArray<dVector4>& Planes =3D (dArray<dVector4>&)Data->Planes;
return Planes.data();
}
int dcGeomFrustumAddPlane(dGeomID g, const dVector4 Plane){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
=09
dArray<dVector4>& Planes =3D (dArray<dVector4>&)Data->Planes;
dVector4& New =3D Planes.push();
New[0] =3D Plane[0];
New[1] =3D Plane[1];
New[2] =3D Plane[2];
New[3] =3D Plane[3];
g->flags |=3D dxGeomMoved;
return Planes.size() - 1;
}
void dcGeomFrustumDelPlane(dGeomID g, int Index){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
=09
dArray<dVector4>& Planes =3D (dArray<dVector4>&)Data->Planes;
Planes.remove(Index);
g->flags |=3D dxGeomMoved;
}
void dcGeomFrustumSetPlane(dGeomID g, int Index, const dVector4 Plane){
dxFrustum* Data =3D (dxFrustum*)CLASSDATA(g);
=09
dArray<dVector4>& Planes =3D (dArray<dVector4>&)Data->Planes;
Planes[Index][0] =3D Plane[0];
Planes[Index][1] =3D Plane[1];
Planes[Index][2] =3D Plane[2];
Planes[Index][3] =3D Plane[3];
g->flags |=3D dxGeomMoved;
}
------=_NextPart_000_002E_01C312F0.CBAF4C20
Content-Type: application/octet-stream;
name="dxFrustum.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="dxFrustum.h"
#include "array.h"
// This may look weird, but it saves 12 bytes of ram
union dxFrustum{
dVector4 Plane;
char Planes[sizeof(dArray<dVector4>)];
};
------=_NextPart_000_002E_01C312F0.CBAF4C20
Content-Type: application/octet-stream;
name="dFrustum.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="dFrustum.h"
extern GLOBAL_SHAREDLIB_SPEC int dcFrustumClass;
dGeomID dcCreateFrustum (dSpaceID space, const dVector4* Planes, int =
PlaneCount);
void dcGeomFrustumSetPlanes(dGeomID g, const dVector4* Planes, int =
PlaneCount);
const dVector4* dcGeomFrustumGetPlanes(dGeomID g);
int dcGeomFrustumGetPlaneCount(dGeomID g);
int dcGeomFrustumAddPlane(dGeomID g, const dVector4 Plane);
void dcGeomFrustumDelPlane(dGeomID g, int Index);
void dcGeomFrustumSetPlane(dGeomID g, int Index, const dVector4 Plane);
------=_NextPart_000_002E_01C312F0.CBAF4C20--