[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--