Help with clipping code - also question about rounding fp!

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
subbie
Posts: 122
Joined: Thu May 05, 2005 4:14 am

Help with clipping code - also question about rounding fp!

Post by subbie »

Hey, a while back I made a 3d engine based on the quake 3 file formats. A while back I added in code to clip my surfaces but I have a few problems with it. For some reason the cordinates & UV clip fine but the colors dont clip properly. like if far away I could have a surface with a shadow starting from the bottom left going to the top right. Yet when I get closer and closer (when my clipping kicks in) the colors shift to the oposite side (going from |/| to |\|).

Here is my code. Any idea's?

As you can guess from the code the cordinates & UV's are floating point but the color is 32bit 8888 RGBA.

Code: Select all

int ClipLineToPlane( Quake3BspPlane* pPlane, BspClipVertex* vStart, BspClipVertex* vEnd )
{
	//* Clip Return Status
	//* 00 = Point Not Visable (save neither point)
	//* 01 = Save Start Point
	//* 10 = Save End Point
	//* 11 = Save Both Points

	float fStartDistance = IsPointVisableFloat( pPlane, vStart->x, vStart->y, vStart->z );
	float fEndDistance = IsPointVisableFloat( pPlane, vEnd->x, vEnd->y, vEnd->z );

	float fInverDistance = 1.0f;
	float fFraction = 0.0f;

	float uColor1[4];
	float uColor2[4];
	float uColor3[4];

	BspClipVertex vNewPoint;

	//* Both Points Visable
	if( ( fStartDistance >= 0 ) && ( fEndDistance >= 0 ) )
		return 1;

	//* Both Points Not Visable
	if&#40; &#40; fStartDistance < 0 &#41; && &#40; fEndDistance < 0 &#41; &#41;
		return 0;

	//* Calculate Inverse
	if&#40; &#40; fStartDistance - fEndDistance &#41; != 0 &#41;
		fInverDistance = 1.0f / &#40; fStartDistance - fEndDistance &#41;;

	//* Get Fractional Value
	fFraction = &#40; fStartDistance &#41; * fInverDistance;

	//* Let it go outside the bounds a bit so we dont clip too early
	if&#40; fStartDistance > fEndDistance &#41;
		fFraction += EPSILON2;
	else
		fFraction -= EPSILON2;

	//* Verify it's valid
	if&#40; fFraction < 0.0f &#41;
		fFraction = 0.0f;
	else if&#40; fFraction > 1.0f &#41;
		fFraction = 1.0f;

	//* Generate Point of Intersection
	vNewPoint.x = vStart->x + &#40; fFraction * &#40; vEnd->x - vStart->x &#41; &#41;;
	vNewPoint.y = vStart->y + &#40; fFraction * &#40; vEnd->y - vStart->y &#41; &#41;;
	vNewPoint.z = vStart->z + &#40; fFraction * &#40; vEnd->z - vStart->z &#41; &#41;;

	//* Generate UVs
	vNewPoint.u = vStart->u + &#40; fFraction * &#40; vEnd->u - vStart->u &#41; &#41;;
	vNewPoint.v = vStart->v + &#40; fFraction * &#40; vEnd->v - vStart->v &#41; &#41;;

	//* Generate Color
	uColor2&#91;0&#93; = &#40;float&#41;vStart->color&#91;0&#93; / 255.0f;
	uColor2&#91;1&#93; = &#40;float&#41;vStart->color&#91;1&#93; / 255.0f;
	uColor2&#91;2&#93; = &#40;float&#41;vStart->color&#91;2&#93; / 255.0f;
	uColor2&#91;3&#93; = &#40;float&#41;vStart->color&#91;3&#93; / 255.0f;

	uColor3&#91;0&#93; = &#40;float&#41;vEnd->color&#91;0&#93; / 255.0f;
	uColor3&#91;1&#93; = &#40;float&#41;vEnd->color&#91;1&#93; / 255.0f;
	uColor3&#91;2&#93; = &#40;float&#41;vEnd->color&#91;2&#93; / 255.0f;
	uColor3&#91;3&#93; = &#40;float&#41;vEnd->color&#91;3&#93; / 255.0f;

	uColor1&#91;0&#93; = uColor2&#91;0&#93; + &#40; fFraction * &#40;uColor3&#91;0&#93; - uColor2&#91;0&#93;&#41; &#41;;
	uColor1&#91;1&#93; = uColor2&#91;1&#93; + &#40; fFraction * &#40;uColor3&#91;1&#93; - uColor2&#91;1&#93;&#41; &#41;;
	uColor1&#91;2&#93; = uColor2&#91;2&#93; + &#40; fFraction * &#40;uColor3&#91;2&#93; - uColor2&#91;2&#93;&#41; &#41;;
	uColor1&#91;3&#93; = uColor2&#91;3&#93; + &#40; fFraction * &#40;uColor3&#91;3&#93; - uColor2&#91;3&#93;&#41; &#41;;

	//* Store Point
	if&#40; fStartDistance > fEndDistance &#41;
	&#123;
		vEnd->x = vNewPoint.x;
		vEnd->y = vNewPoint.y;
		vEnd->z = vNewPoint.z;
		vEnd->u = vNewPoint.u;
		vEnd->v = vNewPoint.v;

		//vEnd->color = uColor1&#91;0&#93; + &#40; uColor1&#91;1&#93; << 8&#41; + &#40; uColor1&#91;2&#93; << 16&#41; + &#40; uColor1&#91;3&#93; << 24&#41;;
		vEnd->color&#91;0&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;0&#93; * 255.0f &#41;;
		vEnd->color&#91;1&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;1&#93; * 255.0f &#41;;
		vEnd->color&#91;2&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;2&#93; * 255.0f &#41;;
		vEnd->color&#91;3&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;3&#93; * 255.0f &#41;;

		//* Line Clipped &#40;Save both Points&#41;
		return 3;
	&#125;
	else
	&#123;
		vStart->x = vNewPoint.x;
		vStart->y = vNewPoint.y;
		vStart->z = vNewPoint.z;
		vStart->u = vNewPoint.u;
		vStart->v = vNewPoint.v;

		//vStart->color = uColor1&#91;0&#93; + &#40; uColor1&#91;1&#93; << 8&#41; + &#40; uColor1&#91;2&#93; << 16&#41; + &#40; uColor1&#91;3&#93; << 24&#41;;
		vStart->color&#91;0&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;0&#93; * 255.0f &#41;;
		vStart->color&#91;1&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;1&#93; * 255.0f &#41;;
		vStart->color&#91;2&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;2&#93; * 255.0f &#41;;
		vStart->color&#91;3&#93; = &#40;unsigned char&#41;&#40; uColor1&#91;3&#93; * 255.0f &#41;;
	&#125;

	//* Line Clipped
	return 1;
&#125;
--edit--

I have another question. I have also been working on a n64 emulator called monkey64. Some of the n64 floating point unit seems to control how it wants values rounded. Is there a way I can set and controll this on the psp?
Post Reply