• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
cozzie

linking a pos/neg value, just as pointer?

9 posts in this topic

Hi,

I have a fairly simple question (I think), on which I'm afraid I'm thinking to simple.

Here's what I want to achieve:

 

Class: camera

Members: 

6 frustumplanes (mFrustumPlane[6])

2 d3dxvector3's (XYZ), pVtx, nVtx (positive and negative extents of a bounding box)

 

Struct:

bounding box

Members:

2 d3dxvector3's (XYZ) with min and max extens of a bounding box

 

What do I do know:

- for each bounding box check, I check which X, Y, Z from the min/max vertices I need to use to fill the pVtx/nVtx

- this is done for each of the 6 planes, within each bounding box check

- the normal per plane determines which X, Y, Z I need to use from the min and max vertices of the box

 

What do I want to do:

- for each frame, determine which min/ max X Y Z values I need to use

- reuse this information for each bounding box check

 

So I have to find a way to do the following:

- within update frustum function: determine per plane if the X, Y and Z are positive or negative (and save this information)

- withing bounding box check function: continue directly using the correct min and max XYZ vertices values, based on the normal per plane (positive or negative X Y Z)

 

I thought of doing thing by creatig a X, Y, Z bool per plane of the frustum, and set to true when the X/ Y or Z is positive and to false, when it's negative. Then I don't need to check this for each bounding box check.

 

The only thing is, that I would then still need to check the bool values for each box check.

Can someone help me in the right direction?

 

Here's the current code of the bounding box check function:

 

int CD3dcam::BoxInFrustum(BOUNDINGBOX *pBoundingBox)
{
	bool intersect = false;
	float dist;

	for(int i=0;i<6;++i)
	{
		// find the nearest and farthest point along normal direction
		_pvtx = pBoundingBox->min;
		if(mFrustumPlane[i].a >= 0) _pvtx.x = pBoundingBox->max.x;
		if(mFrustumPlane[i].b >= 0) _pvtx.y = pBoundingBox->max.y;
		if(mFrustumPlane[i].c >= 0) _pvtx.z = pBoundingBox->max.z;

		_nvtx = pBoundingBox->max;
		if(mFrustumPlane[i].a >= 0) _nvtx.x = pBoundingBox->min.x;
		if(mFrustumPlane[i].b >= 0) _nvtx.y = pBoundingBox->min.y;
		if(mFrustumPlane[i].c >= 0) _nvtx.z = pBoundingBox->min.z;

		// check positive vertex; further along the normal's direction
		dist = D3DXPlaneDotCoord(&mFrustumPlane[i], &_pvtx);
		if(dist < 0) return OUTSIDE;		// wrong side of plane, completely outside

		// check negative vertex; less far along the normal's direction
		dist = D3DXPlaneDotCoord(&mFrustumPlane[i], &_nvtx);
		if(dist < 0) intersect = true; // return INTERSECT;  	// intersecting, negative vertex within frustum
	}
	if(intersect) return INTERSECT;
	return INSIDE;
}

 

0

Share this post


Link to post
Share on other sites

What's the question?? What are you trying to do? It's not very clear from your post.

Is there something wrong with the code or you're looking for optimizing it??

Edited by jbadams
Restored post contents from history.
0

Share this post


Link to post
Share on other sites

Hi vortez. Thanks for the reaction.

I'll try to explain with a small code example below (similar principle)

 

What I basically want to do is 'save a pointer' which I can use in another function.

Currently I do the check for each plane's normal every time I run CheckAABB instead doing it once in UpdateFrustum (the normals of the planes only change once per frame/ UpdateFrustum). So I want to get rid of 'if checking' the same over and over again when it doesn't change.

 

Hope this clears up the question.

 

typedef struct VECTOR3
{
	float x, y, z;
} VECTOR3;

typedef struct PLANE
{
	VECTOR3		normal;
	float		distance;
} PLANE;

typedef struct AABB
{
	VECTOR3		corners[8];
} AABB;

class myFrustum
{
	PLANE		mPlanes[6];
	VECTOR3		positiveExtent;
	VECTOR3		negativeExtent;

	void UpdateFrustum();
	void CheckAABB(VECTOR3 pMin, VECTOR3 pMax);
}

void myFrustum::UpdateFrustum()
{
	// calculate the actual frustum planes (not relevant to this example)
	// mPlanes[ ] is updated using new matrices etc

	for(i=0;i<6;++i)
	{
		if(mPlanes[i].x > 0) 
			// ......: store that plane[i] has positive X value OR 
			// that in CheckAABB pMax.x needs to be used

		if(mPlanes[i].x < 0) 
			// ......: store that plane[i] has negative X value OR 
			// that in CheckAABB pMin.x needs to be used

		// DO the same for Y and Z values
	}
}

void myFrustum::CheckAABB(VECTOR3 pMin, VECTOR3 pMax)
{
	positiveExtent.x = // pMin.x of pMax.x, depending on what 'pointer' is stored in UpdateFrustum function
}
0

Share this post


Link to post
Share on other sites
You need the bounding box centre and size instead of min and max, then each plane can store a sign per component.

pvtx.x = centre.x + size.x * plane.sign.x

If for some reason you need to store min and max, you can calculate centre and size quite easily.
0

Share this post


Link to post
Share on other sites

Hi clay.

Thanks, sounds like a very good solution, I'll go work on it.

 

Alhtough I don't now how to set a '+' or '-' value to a variable, what type would that be? (no int)

0

Share this post


Link to post
Share on other sites

Hi clay.

Thanks, sounds like a very good solution, I'll go work on it.

 

Alhtough I don't now how to set a '+' or '-' value to a variable, what type would that be? (no int)

a bool would work. but that's an int in c++ however...

you also may want to consider using bounding spheres instead of boxes, if your application allows that. (point-plane-distance test is easy and quick, no fiddling with signs :) )

0

Share this post


Link to post
Share on other sites
Float is best for the sign as you are going to use it to multiply another float.
0

Share this post


Link to post
Share on other sites

Thanks, I'll probaly just use an integer, where negative sign would be '-1' and positive '1'.

Multiplying will then give me the needed result

 

update; replies just passed each other, i'll use a float then with either -1.0f or +1.0f as value to multiply by

Edited by cozzie
0

Share this post


Link to post
Share on other sites

Thanks all, just implemented it and all looks good.

Some code 'snippets':

 

// creating the AABB, NEW: calculate center and size

void CreateAABB(TVERTEX *pVtxArray, DWORD pStart, DWORD pNr, BOUNDINGBOX *pBox)
{
	// MIN and MAX vertices
	pBox->min.x = pVtxArray[pStart].position.x;
	pBox->min.y = pVtxArray[pStart].position.y;
	pBox->min.z = pVtxArray[pStart].position.z;

	pBox->max.x = pVtxArray[pStart].position.x;
	pBox->max.y = pVtxArray[pStart].position.y;
	pBox->max.z = pVtxArray[pStart].position.z;

	for(DWORD vc=pStart;vc<pStart+pNr;++vc)
	{
		if(pVtxArray[vc].position.x < pBox->min.x) pBox->min.x = pVtxArray[vc].position.x;
		if(pVtxArray[vc].position.x > pBox->max.x) pBox->max.x = pVtxArray[vc].position.x;

		if(pVtxArray[vc].position.y < pBox->min.y) pBox->min.y = pVtxArray[vc].position.y;
		if(pVtxArray[vc].position.y > pBox->max.y) pBox->max.y = pVtxArray[vc].position.y;

		if(pVtxArray[vc].position.z < pBox->min.z) pBox->min.z = pVtxArray[vc].position.z;
		if(pVtxArray[vc].position.z > pBox->max.z) pBox->max.z = pVtxArray[vc].position.z;
	}

	pBox->size.x = pBox->max.x - pBox->min.x;
	pBox->size.y = pBox->max.y - pBox->min.y;
	pBox->size.z = pBox->max.z - pBox->min.z;

	pBox->center = pBox->max - (pBox->size / 2.0f);

	// FULL 8 vertices of the AABB		
	pBox->boxArrayBase[0].x = pBox->min.x;
	pBox->boxArrayBase[0].y = pBox->min.y;
	pBox->boxArrayBase[0].z = pBox->min.z;

	pBox->boxArrayBase[1].x = pBox->max.x;
	pBox->boxArrayBase[1].y = pBox->max.y;
	pBox->boxArrayBase[1].z = pBox->max.z;

	pBox->boxArrayBase[2].x = pBox->max.x;
	pBox->boxArrayBase[2].y = pBox->max.y;
	pBox->boxArrayBase[2].z = pBox->min.z;

	pBox->boxArrayBase[3].x = pBox->min.x;
	pBox->boxArrayBase[3].y = pBox->max.y;
	pBox->boxArrayBase[3].z = pBox->min.z;

	pBox->boxArrayBase[4].x = pBox->min.x;
	pBox->boxArrayBase[4].y = pBox->min.y;
	pBox->boxArrayBase[4].z = pBox->max.z;

	pBox->boxArrayBase[5].x = pBox->max.x;
	pBox->boxArrayBase[5].y = pBox->min.y;
	pBox->boxArrayBase[5].z = pBox->max.z;

	pBox->boxArrayBase[6].x = pBox->max.x;
	pBox->boxArrayBase[6].y = pBox->min.y;
	pBox->boxArrayBase[6].z = pBox->min.z;

	pBox->boxArrayBase[7].x = pBox->min.x;
	pBox->boxArrayBase[7].y = pBox->max.y;
	pBox->boxArrayBase[7].z = pBox->max.z;

	pBox->created = true;
}

// update AABB, NEW: update center and size

bool UpdateAABB(BOUNDINGBOX *pBox)
{
	if(!pBox->created) return false;

//	8 AABB corners need to be transformed by the latest world matrix
//	now find the 2 extents

	pBox->min.x = pBox->boxArray[0].x;
	pBox->min.y = pBox->boxArray[0].y;
	pBox->min.z = pBox->boxArray[0].z;

	pBox->max.x = pBox->boxArray[0].x;
	pBox->max.y = pBox->boxArray[0].y;
	pBox->max.z = pBox->boxArray[0].z;

	for(int vc=0;vc<8;++vc)
	{
		if(pBox->boxArray[vc].x < pBox->min.x) pBox->min.x = pBox->boxArray[vc].x;
		if(pBox->boxArray[vc].x > pBox->max.x) pBox->max.x = pBox->boxArray[vc].x;

		if(pBox->boxArray[vc].y < pBox->min.y) pBox->min.y = pBox->boxArray[vc].y;
		if(pBox->boxArray[vc].y > pBox->max.y) pBox->max.y = pBox->boxArray[vc].y;

		if(pBox->boxArray[vc].z < pBox->min.z) pBox->min.z = pBox->boxArray[vc].z;
		if(pBox->boxArray[vc].z > pBox->max.z) pBox->max.z = pBox->boxArray[vc].z;
	}

	pBox->size.x = pBox->max.x - pBox->min.x;
	pBox->size.y = pBox->max.y - pBox->min.y;
	pBox->size.z = pBox->max.z - pBox->min.z;

	pBox->center = pBox->max - (pBox->size / 2.0f);

	return true;
}

// remark: the full 8 corners (boxArray) are transformed each frame as input

/* checking the AABB with frustum */

// part of UpdateFrustum

	for(int i=0;i<6;++i)
	{
		D3DXPlaneNormalize(&mFrustumPlane[i], &mFrustumPlane[i]);

		// calculate sign (+ or -) per frustum plane, to find P/N vertex in AABB checks
		if(mFrustumPlane[i].a >= 0) mFrustumPlaneSign[i].x = 1.0f;
		if(mFrustumPlane[i].a < 0)	mFrustumPlaneSign[i].x = -1.0f;

		if(mFrustumPlane[i].b >= 0) mFrustumPlaneSign[i].y = 1.0f;
		if(mFrustumPlane[i].b < 0)	mFrustumPlaneSign[i].y = -1.0f;

		if(mFrustumPlane[i].c >= 0) mFrustumPlaneSign[i].z = 1.0f;
		if(mFrustumPlane[i].c < 0)	mFrustumPlaneSign[i].z = -1.0f;
	}

// part of checking the AABB function

		// find the nearest and farthest point along normal direction
		_pvtx.x = pBoundingBox->center.x + (pBoundingBox->size.x / 2.0f) * mFrustumPlaneSign[i].x;
		_pvtx.y = pBoundingBox->center.y + (pBoundingBox->size.y / 2.0f) * mFrustumPlaneSign[i].y;
		_pvtx.z = pBoundingBox->center.z + (pBoundingBox->size.z / 2.0f) * mFrustumPlaneSign[i].z;

		_nvtx.x = pBoundingBox->center.x - (pBoundingBox->size.x / 2.0f) * mFrustumPlaneSign[i].x;
		_nvtx.y = pBoundingBox->center.y - (pBoundingBox->size.y / 2.0f) * mFrustumPlaneSign[i].y;
		_nvtx.z = pBoundingBox->center.z - (pBoundingBox->size.z / 2.0f) * mFrustumPlaneSign[i].z;



 

Still struggling though with some rotation issues (if ! 90, 180, 270 or 360 degrees).

If some wants to take a peek, includes link to youtube capture:

http://www.gamedev.net/topic/640198-strange-rotation-sympton-aabb-extents-with-video/

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0