Jump to content

  • Log In with Google      Sign In   
  • Create Account


Collision coordinate junk!?!? (full main source code)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 theo2005   Members   -  Reputation: 114

Like
0Likes
Like

Posted 06 August 2012 - 01:43 PM

I've been fighting with this for a few months now and nothing worked...

Please help me out. I do not know what is causing this, but my hunch is that it has something to do with world transforms and vector coordinate transforms. I really am on the verge of giving up on 3D programming because of this..

Don't mind the collision checks.
The problem basically is that what I'm getting for my bounding box coordinates is junk.
Junk like...

Object 0: 8.83098e-042 0 0
Object 3: 5 14.3369 1.17549e-038

#include <windows.h>
#include <windowsx.h> //has something to do with the window class << EX >> (newer window class)
#include <d3d9.h>
#include <d3dx9.h> //matrix stuff
#include <dinput.h> //directInput
#include <sstream>
#include <iostream>
#include <fstream>
#include "XAnimator_lib.h"
// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
//directInput stuff
#pragma comment (lib, "dinput8.lib") //why 8? Because 9 had no significant changes
#pragma comment (lib, "dxguid.lib")
// define the screen resolution
#define SCREEN_WIDTH  800 // in CCamera as well
#define SCREEN_HEIGHT 600
#define WALL 2
#define FLOOR 1
#define SKELE 0
// global declarations
LPDIRECT3D9 d3d;	// the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev;	// the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;	// the pointer to the vertex buffer
LPDIRECT3DINDEXBUFFER9 i_buffer; //create the index buffer
//directInput stuff
LPDIRECTINPUT8 din;	// the pointer to our DirectInput interface
LPDIRECTINPUTDEVICE8 dinkeyboard;	// the pointer to the keyboard device
LPDIRECTINPUTDEVICE8 dinmouse;	// the pointer to the mouse device
BYTE keystate[256];	// the storage for the key-information
DIMOUSESTATE mousestate;	// the storage for the mouse-information
void cleanD3D()
{
	v_buffer->Release();	// close and release the vertex buffer
	d3ddev->Release();	// close and release the 3D device
	d3d->Release();	// close and release Direct3D
}
// this is the function that closes DirectInput
void cleanDInput()
{
	dinkeyboard->Unacquire();	// make sure the keyboard is unacquired
	dinmouse->Unacquire();	// make sure the mouse in unacquired
	din->Release();	// close DirectInput before exiting
}

//function prototypes
void FileWrite (float PosX, float PosY, float PosZ, float LookX, float LookY, float LookZ);
void CleanDynamicVariables ();
void render_frame();	// renders a single frame
void init_graphics();	// 3D declarations
void init_light ();
//directinput stuff
void initDInput(HINSTANCE hInstance, HWND hWnd);	// sets up and initializes DirectInput
void detect_input();	// gets the current input state
bool LoadModel(const std::string &filename);
void ProcessInput( long xDelta, long yDelta, long zDelta, float elapsedTime );
inline void SetObjectCoords ();
void RenderOOBB(D3DXVECTOR3 *corners, int ObjNum);
void RenderBoundingBoxes(int ObjNum);

//checks n' bools
bool IsFullscreen = FALSE; //fullscreen, here we come!
bool FirstTime = TRUE;
bool Movement = TRUE;
IXAnimator * XAnimator=0;
VOID* pVoid;	// a void pointer
int  ObjectQuantity = 0; //we find out later
static int countZ = 0;
int * ModelID = new int [ObjectQuantity];
int * NumAnimationSets= new int[ObjectQuantity];
int * CurrentAnimationSet = new int[ObjectQuantity];
DWORD * lastTimeAnimationChanged = new DWORD [ObjectQuantity];
DWORD * lastUpdateTime = new DWORD [ObjectQuantity];
DWORD * timeElapsedSinceAnimationChange = new DWORD[ObjectQuantity];
DWORD * timeElapsedSinceLastUpdate =  new DWORD[ObjectQuantity];
// Transition time between animation sets in ms
float TransitionTime=2500;
// Time before we switch to the next animation in ms
DWORD TimeBeforeNextAnimation=4000;
float * TranslateX = new float[ObjectQuantity];
float * TranslateY = new float[ObjectQuantity];
float * TranslateZ = new float[ObjectQuantity];
D3DXMATRIX IdentityMatrix;

//headerfiles (mostly functions) --....
#include "CenterScreen.h"
#include "InitD3D.h"
#include "CCamera.h"
#include "CTimer.h"
void Pause( BOOL rendering, BOOL timer ); //needs to be h ere because of CTimer.h
struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR;}; //D3DVECTOR NORMAL DWORD COLOR
//#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL)
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)

LRESULT CALLBACK WindowProc(HWND hWnd,
						 UINT message,
						 WPARAM wParam,
						 LPARAM lParam);

CCamera Camera;
CTimer Timer;
//CMovement Movement;
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
//------------------------------------------------------------ WINDOW STUFF ------------------------------------------------------//
	HWND hWnd;
	WNDCLASSEX wc;
	// clear out the window class for use
	ZeroMemory(&wc, sizeof(WNDCLASSEX));
	// fill in the struct with the needed information
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW; //redraw the window when moved
	wc.lpfnWndProc = WindowProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	//wc.hbrBackground = (HBRUSH)COLOR_WINDOW;  //(important to comment out to make the game look professinal in full screen)
	wc.lpszClassName = L"WindowClass1";
	// register the window class
	RegisterClassEx(&wc);
	// create the window and use the result as the handle
DWORD style;
	if (IsFullscreen == TRUE)
{
  style = WS_EX_TOPMOST | WS_POPUP;
}
else
{
  style = WS_OVERLAPPEDWINDOW;
}
hWnd = CreateWindowEx(NULL,
						  L"WindowClass1",	// name of the window class
		L"My first 3D program",   // title of the window
						  style,	// window style (buttons)
						  0,	// x-position of the window LEFT RIGHT  currently FC value
						  0,	// y-position of the window UP DOWN currently FC value
						  SCREEN_WIDTH,	// width of the window
						  SCREEN_HEIGHT,	// height of the window
						  NULL,	// we have no parent window, NULL
						  NULL,	// we aren't using menus, NULL
						  hInstance,	// application handle
						  NULL);	// used with multiple windows, NULL
if (IsFullscreen == FALSE)
{
		HWND TempWnd = NULL;
	 TempWnd = GetDesktopWindow ();
  CenterWindow(hWnd, TempWnd); //center window relative to desktop
}
	// display the window on the screen
nCmdShow = SW_SHOWNORMAL; //just in case..
	ShowWindow(hWnd, nCmdShow);
//-------------------------------------------------------- WINDOW STUFF ----------------------------------------------------------------------//
	initD3D(hWnd);
	initDInput(hInstance, hWnd);	// initialize DirectInput
Pause( FALSE, FALSE ); //Timer start
XAnimator=CreateXAnimator(d3ddev);
if (!XAnimator)
{
  return 0;
}
	if (!LoadModel ("Data\\bones_all.x"))
{
  return 0;
}
if (!LoadModel("Data\\floor.x"))
{
  return 0;
}
if (!LoadModel("Data\\wall.x"))
{
  return 0;
}
if (!LoadModel("Data\\BOX.x"))
{
  return 0;
}
	// this struct holds Windows event messages
	MSG msg;
   // Enter the infinite message loop
	while(TRUE)
	{
		// Check to see if any messages are waiting in the queue
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //PM_REMOVE removes messages after processing
		{
			// translate keystroke messages into the right format
			TranslateMessage(&msg);
			// send the message to the WindowProc function
			DispatchMessage(&msg);
		}
	  
		if(msg.message == WM_QUIT) // exits the while loop
  {
			break;
  }
		detect_input();	// update the input data before rendering
		//if the while loop still goes on, then draw the frame (see the function below)
		render_frame();
		if(keystate[DIK_ESCAPE] & 0x80) //0x80 is for the last bit of information about the keystroke that we need
  {
			PostMessage(hWnd, WM_DESTROY, 0, 0);
  }
	}
	cleanD3D();  //cleans up DirectX and COM
	cleanDInput();	// release DirectInput
//CleanDynamicVariables ();
	return msg.wParam; // return this part of the WM_QUIT message to Windows
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //as much as I understand, windows can CALLBACK this func. when it needs to anytime
{
	// sort through and find what code to run for the message given
	switch(message)
	{
	  
		 case WM_DESTROY: //if the user closed the window
		 {		  
			 PostQuitMessage(0); //send the WM_QUIT message which will trigger the if statement which break;'s the while loop
	 return 0;		   //important to return 0 so that DefwindowProc knows that this case was handled
	 }
   break;
	}
	// Handle any messages the switch statement didn't
	return DefWindowProc (hWnd, message, wParam, lParam);
}

// this is the function used to render a single frame
void render_frame()
{
	// clear the window to a deep blue
	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
	d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); //clear the z-buffer to black
	d3ddev->BeginScene();	// begins the 3D scene
//---------------------------------------------------------- SET UP THE PIPELINE <start> ---------------------------------------------------------------------//

static D3DXMATRIX * matTranslate = new D3DXMATRIX[ObjectQuantity];
	static D3DXMATRIX * matRotateX = new D3DXMATRIX[ObjectQuantity];  
static D3DXMATRIX * matRotateY = new D3DXMATRIX[ObjectQuantity];
static float Index = 0.0f;
if (FirstTime == TRUE)
{
  for (int TimeCount = 0; TimeCount < ObjectQuantity; ++ TimeCount)
  {
		lastTimeAnimationChanged[TimeCount]=timeGetTime();
		lastUpdateTime[TimeCount]=timeGetTime();
	 D3DXMatrixIdentity(&matRotateY[TimeCount]);
	 D3DXMatrixIdentity(&matRotateX[TimeCount]);
	 D3DXMatrixIdentity(&matTranslate[TimeCount]);
	
  }
  D3DXMatrixIdentity(&IdentityMatrix);
  SetObjectCoords ();
	 FirstTime = FALSE;
}
Timer.Update();
float elapsedTime = Timer.GetElapsedTime ();
float MovementSpeed = 4.0f;
if (Movement == TRUE)
{
if(keystate[DIK_UP] & 0x80)
	{
	  
  TranslateZ[SKELE] -=  (cos(Index) * MovementSpeed * elapsedTime );
  //Camera.MoveForward(-cos(Index) * MovementSpeed * elapsedTime );
  TranslateX[SKELE] -= (sin(Index) * MovementSpeed * elapsedTime );
  //Camera.Strafe(-sin(Index) * MovementSpeed * elapsedTime );
  if (timeElapsedSinceAnimationChange[SKELE] > TimeBeforeNextAnimation)
  {
	   XAnimator->ChangeAnimationSet(ModelID[SKELE],1 ,200); //TransitionTime = 200
	lastTimeAnimationChanged[SKELE] = timeGetTime();
  } //animationsets not in the right order? 0 seems to be running
	}
	if(keystate[DIK_LEFT] & 0x80)
	{
  Index -= 3.0f * elapsedTime;
		D3DXMatrixRotationY(&matRotateY[SKELE], Index);
  //Camera.Yaw(D3DXToRadian(-Index));
	}
	if(keystate[DIK_DOWN] & 0x80)
	{
		//TranslateZ[SKELE] += ( -MovementSpeed * elapsedTime );
  TranslateZ[SKELE] +=  (cos(Index) * MovementSpeed * elapsedTime );
  TranslateX[SKELE] += (sin(Index) * MovementSpeed * elapsedTime );
  //Camera.MoveForward(cos(Index) * MovementSpeed * elapsedTime );
  //Camera.Strafe(sin(Index) * MovementSpeed * elapsedTime );
	}
	if(keystate[DIK_RIGHT] & 0x80)
	{
  Index +=3.0f * elapsedTime;
		D3DXMatrixRotationY(&matRotateY[SKELE], Index);
  //Camera.Yaw(D3DXToRadian(-Index));
	}
}


	for (int CountTime = 0;CountTime < ObjectQuantity; ++CountTime) //do time calculations for all objects
	{
  timeElapsedSinceAnimationChange[CountTime] = timeGetTime()-lastTimeAnimationChanged[CountTime];
	 // Periodically advance to the next animation set
	 if (timeElapsedSinceAnimationChange[CountTime] > TimeBeforeNextAnimation) //TimeBefireNextAnimation = 4000ms
	 {
	if(!(keystate[DIK_UP] & 0x80))
	   {
				CurrentAnimationSet[CountTime]+=1;
			 if (CurrentAnimationSet[CountTime] >= NumAnimationSets[CountTime])  //currentanimationset must not be bigger than total animationsets
			 {
			   CurrentAnimationSet[CountTime]=0; //reset back to start
		  }
	   XAnimator->ChangeAnimationSet(ModelID[CountTime],CurrentAnimationSet[CountTime],TransitionTime); //change the animation set
	}
	   lastTimeAnimationChanged[CountTime] = timeGetTime();
	 }

  
  timeElapsedSinceLastUpdate[CountTime] = timeGetTime() - lastUpdateTime[CountTime];
}


	for (int CountRender = 0;CountRender < ObjectQuantity; ++ CountRender) //draw all the objects despite of which object time calculation is executing
{

   D3DXMatrixTranslation(&matTranslate[CountRender], TranslateX[CountRender], TranslateY[CountRender], TranslateZ[CountRender]);
	  XAnimator->Render(ModelID[CountRender], matRotateY[CountRender] * matTranslate[CountRender]  ,(float)timeElapsedSinceLastUpdate[CountRender]);
}
for (int CountTime = 0; CountTime < ObjectQuantity; ++ CountTime)
{
	  lastUpdateTime[CountTime]=timeGetTime();
}
//---------------------------------------------------------- CAMERA SETUP <start> ----------------------------------------------------------------------------//
	 //float elapsedTime = Timer.GetElapsedTime();
		long xDelta; xDelta = mousestate.lX;
		long yDelta; yDelta = mousestate.lY;
		long zDelta; zDelta = mousestate.lZ;
   //Timer.Update();
   //FileWrite(xDelta);
   static D3DXVECTOR3 * cameraPosition;
		 static D3DXVECTOR3 cameraTarget( 0.0f, 1.0f, 0.0f );
		 static D3DXVECTOR3 cameraUp( 0.0f, 1.0f, 0.0f );
		 ProcessInput( xDelta, yDelta, zDelta, Timer.GetElapsedTime() );
   Camera.Update ();
		 d3ddev->SetTransform( D3DTS_VIEW, Camera.GetViewMatrix () );
   D3DXVECTOR3 * Position = Camera.GetPosition ();
   D3DXVECTOR3 * LookAt = Camera.GetLookAt ();
   float PosX = Position -> x;
   float PosY = Position -> y;
   float PosZ = Position -> z;
   float LookX = LookAt -> x;
   float LookY = LookAt -> y;
   float LookZ = LookAt -> z;
  
  
		 // Set the projection matrix
		 D3DXMATRIX projection;
		 float aspect = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT;
		 D3DXMatrixPerspectiveFovLH( &projection, D3DXToRadian (45), aspect, 0.1f, 1000.0f );
		 d3ddev->SetTransform( D3DTS_PROJECTION, &projection );
	   // select which vertex format we are using. Global variable: #define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
		 d3ddev->SetFVF(CUSTOMFVF);
   d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
		 d3ddev->SetIndices(i_buffer);
   //render the object collision boxes for every object
   for (int count = 0; count < ObjectQuantity; ++count)
   {
   D3DXMatrixMultiply(&IdentityMatrix, &matRotateY[count], &matTranslate[count]);
		   // d3ddev->SetTransform(D3DTS_WORLD, &IdentityMatrix);	// set the world transform
		 D3DXVECTOR3 minBoundsModelSpace,maxBoundsModelSpace; // Model min max values in object space
		 D3DXVECTOR3 sphereCentreModelSpace;	  // Sphere centre in model space
		 float sphereRadius;		  // Sphere radius in model space
		 int numMesh;		   // Number of individual mesh bounds returned by the function
   TMeshBounds *indMeshBoundsModelSpace=XAnimator->GetBoundingShapes(ModelID[count],&minBoundsModelSpace,&maxBoundsModelSpace,&sphereCentreModelSpace,&sphereRadius,&numMesh);
	// We have min and max values, use these to get the 8 corners of the boundingbox
D3DXVECTOR3 cornersInModelSpace[8];
//float * TranslateZ = new float[ObjectQuantity];
cornersInModelSpace[0] = D3DXVECTOR3( minBoundsModelSpace.x, minBoundsModelSpace.y, minBoundsModelSpace.z ); // xyz
cornersInModelSpace[1] = D3DXVECTOR3( maxBoundsModelSpace.x, minBoundsModelSpace.y, minBoundsModelSpace.z ); // Xyz
cornersInModelSpace[2] = D3DXVECTOR3( minBoundsModelSpace.x, maxBoundsModelSpace.y, minBoundsModelSpace.z ); // xYz
cornersInModelSpace[3] = D3DXVECTOR3( maxBoundsModelSpace.x, maxBoundsModelSpace.y, minBoundsModelSpace.z ); // XYz
cornersInModelSpace[4] = D3DXVECTOR3( minBoundsModelSpace.x, minBoundsModelSpace.y, maxBoundsModelSpace.z ); // xyZ
cornersInModelSpace[5] = D3DXVECTOR3( maxBoundsModelSpace.x, minBoundsModelSpace.y, maxBoundsModelSpace.z ); // XyZ
cornersInModelSpace[6] = D3DXVECTOR3( minBoundsModelSpace.x, maxBoundsModelSpace.y, maxBoundsModelSpace.z ); // xYZ
cornersInModelSpace[7] = D3DXVECTOR3( maxBoundsModelSpace.x, maxBoundsModelSpace.y, maxBoundsModelSpace.z ); // XYZ
// Now we transform each corner by the world matrix
static bool DoOnce = true;
static D3DXVECTOR3 ** cornersInWorldSpace = 0;
if (DoOnce == true)
{
cornersInWorldSpace = new D3DXVECTOR3 *[8];
for( int i = 0 ; i < 8 ; i++ )
cornersInWorldSpace[i] = new D3DXVECTOR3[ObjectQuantity];
DoOnce = false;
}
for( int i = 0; i < 8; i++ )
{
  D3DXVec3TransformCoord( &cornersInWorldSpace[i][count], &cornersInModelSpace[i], &IdentityMatrix);
}
  D3DXVECTOR3 * minBoundsWorldSpace = new D3DXVECTOR3[ObjectQuantity];
	 minBoundsWorldSpace[count] = cornersInWorldSpace[0][count];
D3DXVECTOR3 * maxBoundsWorldSpace = new D3DXVECTOR3[ObjectQuantity];
	 maxBoundsWorldSpace[count] = cornersInWorldSpace[0][count];
for (int i=1;i<8;i++)
{
  minBoundsWorldSpace[count].x= min(minBoundsWorldSpace[count].x,cornersInWorldSpace[i][count].x);
  minBoundsWorldSpace[count].y= min(minBoundsWorldSpace[count].y,cornersInWorldSpace[i][count].y);
  minBoundsWorldSpace[count].z= min(minBoundsWorldSpace[count].z,cornersInWorldSpace[i][count].z);
  maxBoundsWorldSpace[count].x= max(maxBoundsWorldSpace[count].x,cornersInWorldSpace[i][count].x);
  maxBoundsWorldSpace[count].y= max(maxBoundsWorldSpace[count].y,cornersInWorldSpace[i][count].y);
  maxBoundsWorldSpace[count].z= max(maxBoundsWorldSpace[count].z,cornersInWorldSpace[i][count].z);
}
if (count == 3) //array starts from 0 not 1, that's why -1 ;; that was wrong..
{
  if (maxBoundsWorldSpace[0].x > minBoundsWorldSpace[3].x)
  {
   Movement = FALSE;
  }
  /*for (int count = 1; count < ObjectQuantity; ++ count) //count 1+ because 0 is skeleton, other objects wont collide
	 {
		for (int CountCorner = 0; CountCorner < 4; ++ CountCorner)
	 {
			if (FrontX[SKELE][0] / BackX[3][0] > 0.98 && FrontX[SKELE][0] / BackX[3][0] < 1)
	  {
	   Movement = FALSE;
	  }
	 /* else
	  {
	   Movement = TRUE;
	  }*/
	 //}
	 //}
  FileWrite(maxBoundsWorldSpace[0].x, maxBoundsWorldSpace[0].y, maxBoundsWorldSpace[0].z,maxBoundsWorldSpace[3].x, maxBoundsWorldSpace[3].y, maxBoundsWorldSpace[3].z);
}
   }

  
// ----------------------------------------------------------- CAMERA SETUP <END> --------------------------------------------------------------------------//
//---------------------------------------------------------- SET UP THE PIPELINE <END> ---------------------------------------------------------------------//
	d3ddev->EndScene();	// ends the 3D scene
	d3ddev->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen
}
// this is the function that puts the 3D models into video RAM
void init_graphics()
{
	  // create the vertices using the CUSTOMVERTEX struct
	// create a vertex buffer interface called v_buffer
	d3ddev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),
							   0,
							   CUSTOMFVF,
							   D3DPOOL_MANAGED,
							   &v_buffer,
							   NULL);
	// create the indices using an int array
	short indices[] =
	{
		0, 1, 2,	// side 1
		2, 1, 3,
		4, 0, 6,	// side 2
		6, 0, 2,
		7, 5, 6,	// side 3
		6, 5, 4,
		3, 1, 7,	// side 4
		7, 1, 5,
		4, 5, 0,	// side 5
		0, 5, 1,
		3, 7, 2,	// side 6
		2, 7, 6,
	};
	// create an index buffer interface called i_buffer
	d3ddev->CreateIndexBuffer(36*sizeof(short),
							  0,
							  D3DFMT_INDEX16,
							  D3DPOOL_MANAGED,
							  &i_buffer,
							  NULL);
	// lock i_buffer and load the indices into it
	i_buffer->Lock(0, 0, (void**)&pVoid, 0);
	memcpy(pVoid, indices, sizeof(indices));
	i_buffer->Unlock();
}
// this is the function that initializes DirectInput
void initDInput(HINSTANCE hInstance, HWND hWnd)
{
	// create the DirectInput interface
	DirectInput8Create(hInstance,	// the handle to the application
					   DIRECTINPUT_VERSION,	// the compatible version
					   IID_IDirectInput8,	// the DirectInput interface version
					   (void**)&din,	// the pointer to the interface
					   NULL);	// COM stuff, so we'll set it to NULL
	// create the keyboard device
	din->CreateDevice(GUID_SysKeyboard,	// the default keyboard ID being used
					  &dinkeyboard,	// the pointer to the device interface
					  NULL);	// COM stuff, so we'll set it to NULL
	din->CreateDevice(GUID_SysMouse,
					  &dinmouse,
					  NULL);
	// set the data format to keyboard format (or mouse format below)
	dinkeyboard->SetDataFormat(&c_dfDIKeyboard);
	dinmouse->SetDataFormat(&c_dfDIMouse);
	// set the control you will have over the keyboard (or mouse below)
	dinkeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
	dinmouse->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); //exclusive to ditch windows with it's mouse pointer
}
// this is the function that gets the latest input data
void detect_input()
{
	// get access if we don't have it already
	dinkeyboard->Acquire();
	dinmouse->Acquire();
	// get the input data
	dinkeyboard->GetDeviceState(256, (LPVOID)keystate);
	dinmouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate); //mousestate is a DIMOUSESTATE struct type
}
void init_light(void)
{
	D3DLIGHT9 light;	// create the light struct
	D3DMATERIAL9 material;	// create the material struct
	ZeroMemory(&light, sizeof(light));	// clear out the light struct for use
	light.Type = D3DLIGHT_DIRECTIONAL;	// make the light type 'directional light'
	light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);	// set the light's color
	light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f);
	d3ddev->SetLight(0, &light);	// send the light struct properties to light #0
	d3ddev->LightEnable(0, TRUE);	// turn on light #0
	ZeroMemory(&material, sizeof(D3DMATERIAL9));	// clear out the struct for use
	material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);	// set diffuse color to white
	material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);	// set ambient color to white
	d3ddev->SetMaterial(&material);	// set the globably-used material to &material
}
bool LoadModel(const std::string &filename)
{
if (!XAnimator->LoadXFile(filename,&ModelID[ObjectQuantity]))
{
  return false;
}
ObjectQuantity ++;
if(countZ < ObjectQuantity) //increases count after loop is run
{
	 NumAnimationSets[countZ]=XAnimator->GetNumberOfAnimationSets(ModelID[countZ]);
	 CurrentAnimationSet[countZ] = 0;
  // First animation set to start with - note: v.small transition time as it is the first
	 XAnimator->ChangeAnimationSet(ModelID[countZ],CurrentAnimationSet[countZ],500); //500 transition time in ms
}
countZ++;
return true;
}
inline void CleanDynamicVariables () //not used because crashes the program if more than two objects
{
delete[] NumAnimationSets;
	delete[] CurrentAnimationSet;
	delete[] lastTimeAnimationChanged;
	delete[] lastUpdateTime;
delete[] timeElapsedSinceLastUpdate;
	delete[] timeElapsedSinceAnimationChange;
	delete XAnimator;
delete[] TranslateX;
	delete[] TranslateY;
	delete[] TranslateZ;
}
void FileWrite (float PosX, float PosY, float PosZ, float LookX, float LookY, float LookZ)
{
	  using namespace std;
	  ofstream File("FileInput.txt");
	  if (File)
	  {
		   // read stuff from FileInputZ and print into file
		   File << PosX << "  " << PosY << "  " << PosZ << endl
		  << LookX << "  " << LookY << "  " << LookZ << endl;
	  }
	
}
void ProcessInput( long xDelta, long yDelta, long zDelta, float elapsedTime )
{
	float cameraSpeed = 10.0f;
  
static bool pressedButtons[4];
for ( int i = 0; i < 4; i++ )
	{
		if ( mousestate.rgbButtons[i] & 0x80 )
		{
			pressedButtons[i] = TRUE;
		}
		else
		{
			pressedButtons[i] = FALSE;
		}
  
	}
//if ( pressedButtons[0] ) //if left mouse click
	//{
		Camera.Yaw( xDelta * elapsedTime * 0.2f);
		Camera.Pitch( yDelta * elapsedTime * 0.2f );
//}

	if(keystate[DIK_W] & 0x80)
	{
		Camera.MoveForward( cameraSpeed * elapsedTime );
	}
	if(keystate[DIK_A] & 0x80)
	{
		Camera.Strafe( -cameraSpeed * elapsedTime );
	}
	if(keystate[DIK_S] & 0x80)
	{
		Camera.MoveForward( -cameraSpeed * elapsedTime );
	}
	if(keystate[DIK_D] & 0x80)
	{
		Camera.Strafe( cameraSpeed * elapsedTime );
	}

}
void Pause( BOOL rendering, BOOL timer )
{
	Timer.m_renderingPauseCount += rendering ? 1 : -1;
	Timer.m_renderingPauseCount = (Timer.m_renderingPauseCount < 0) ? 0 :Timer.m_renderingPauseCount;
	Timer.m_timerPauseCount += timer ? 1 : -1;
	Timer.m_timerPauseCount = (Timer.m_timerPauseCount < 0) ? 0 : Timer.m_timerPauseCount;
	Timer.m_renderingPaused = (Timer.m_renderingPauseCount > 0);
	Timer.m_timerPaused = (Timer.m_timerPauseCount > 0);
	if (Timer.m_timerPaused)
	{
		Timer.Stop();
	}
	else if (!Timer.m_timerPaused)
	{
		Timer.Start();
	}
}
void SetObjectCoords ()
{
  TranslateX[SKELE] = 4.0f;
	 TranslateY[SKELE] = 0.2f;
	 TranslateZ[SKELE] = 3.0f;
  TranslateX[FLOOR] = 0.0f;
  TranslateY[FLOOR] = 0.0f;
  TranslateZ[FLOOR] = 0.0f;
  TranslateX[WALL] = 0.0f;
  TranslateY[WALL] = 0.0f;
  TranslateZ[WALL] = 0.0f;
  TranslateX[3] = 5.0f;
  TranslateY[3] = 0.0f;
  TranslateZ[3] = 0.0f;
}
//boundingboxes stuff starts here
void RenderBoundingBoxes(int ObjNum)
{
/*
Get bounding shape information from XAnimator
The GetBoundingShapes call allows you to get bounding shapes for the whole model and for each mesh within the model
The call has default parameters so you can just extract the min, max bounds of the whole model or, by providing sphere
variables you can also extract the sphere bounds. Finally by providing a variable for numMesh you can also extract
boudning data for each mesh within the model.
Note that the bounding data depends on the current animation of the model (from the last time it was animated)
*/
D3DXVECTOR3 minBoundsModelSpace,maxBoundsModelSpace; // Model min max values in object space
D3DXVECTOR3 sphereCentreModelSpace;	  // Sphere centre in model space
float sphereRadius;		  // Sphere radius in model space
int numMesh;		   // Number of individual mesh bounds returned by the function
// Get all the bounds information from XAnimator
TMeshBounds *indMeshBoundsModelSpace=XAnimator->GetBoundingShapes(ModelID[ObjNum],&minBoundsModelSpace,&maxBoundsModelSpace,&sphereCentreModelSpace,&sphereRadius,&numMesh);
/*
Model Oriented Bounding Box (OBB)
XAnimator returns all bounds values in model space. We need to convert these to world space
We do this by using the same world matrix we used to draw the model
When transforming from object space to world space we will lose the axis-aligned nature of the bounds
Meaning we cannot just store min and max values but must store all 8 corners of the box
Therefore the first step is to create the 8 corners
*/
// We have min and max values, use these to get the 8 corners of the boundingbox
D3DXVECTOR3 cornersInModelSpace[8];
cornersInModelSpace[0] = D3DXVECTOR3( minBoundsModelSpace.x, minBoundsModelSpace.y, minBoundsModelSpace.z ); // xyz
cornersInModelSpace[1] = D3DXVECTOR3( maxBoundsModelSpace.x, minBoundsModelSpace.y, minBoundsModelSpace.z ); // Xyz
cornersInModelSpace[2] = D3DXVECTOR3( minBoundsModelSpace.x, maxBoundsModelSpace.y, minBoundsModelSpace.z ); // xYz
cornersInModelSpace[3] = D3DXVECTOR3( maxBoundsModelSpace.x, maxBoundsModelSpace.y, minBoundsModelSpace.z ); // XYz
cornersInModelSpace[4] = D3DXVECTOR3( minBoundsModelSpace.x, minBoundsModelSpace.y, maxBoundsModelSpace.z ); // xyZ
cornersInModelSpace[5] = D3DXVECTOR3( maxBoundsModelSpace.x, minBoundsModelSpace.y, maxBoundsModelSpace.z ); // XyZ
cornersInModelSpace[6] = D3DXVECTOR3( minBoundsModelSpace.x, maxBoundsModelSpace.y, maxBoundsModelSpace.z ); // xYZ
cornersInModelSpace[7] = D3DXVECTOR3( maxBoundsModelSpace.x, maxBoundsModelSpace.y, maxBoundsModelSpace.z ); // XYZ
// Now we transform each corner by the world matrix
D3DXVECTOR3 cornersInWorldSpace[8];
for( int i = 0; i < 8; i++ )
{
  D3DXVec3TransformCoord( &cornersInWorldSpace[i], &cornersInModelSpace[i], &IdentityMatrix);
}
// We now have an oriented bounding box in world space
//RenderOOBB(cornersInWorldSpace, ObjNum);
/*
Model Axis Aligned Bounding Box (OBB)
We could, at a loss in accuracy, convert our OBB in world space to an axis-alinged one in world space
This would make collision detection far easier
To convert we find the min and max values of the 8 corners in world space
*/
D3DXVECTOR3 minBoundsWorldSpace=cornersInWorldSpace[0];
D3DXVECTOR3 maxBoundsWorldSpace=cornersInWorldSpace[0];
for (int i=1;i<8;i++)
{
  minBoundsWorldSpace.x=min(minBoundsWorldSpace.x,cornersInWorldSpace[i].x);
  minBoundsWorldSpace.y=min(minBoundsWorldSpace.y,cornersInWorldSpace[i].y);
  minBoundsWorldSpace.z=min(minBoundsWorldSpace.z,cornersInWorldSpace[i].z);
  maxBoundsWorldSpace.x=max(maxBoundsWorldSpace.x,cornersInWorldSpace[i].x);
  maxBoundsWorldSpace.y=max(maxBoundsWorldSpace.y,cornersInWorldSpace[i].y);
  maxBoundsWorldSpace.z=max(maxBoundsWorldSpace.z,cornersInWorldSpace[i].z);
}

//RenderAABBox(minBoundsWorldSpace,maxBoundsWorldSpace,D3DCOLOR_XRGB(255,0,0));

/* Model individual mesh
XAnimator also returns an array of boundign boxes for each individual mesh in the model. These can be used for
very accurate collisions e.g. just with a foot or a hand.
*/
/*for (int i=0;i<numMesh;i++)
{
  // Again we need to transform each one into world space
  D3DXVECTOR3 indMeshOBBWorldSpace[8];
  // Transform the 8 corners of our object space bounding box into world space
  for( int j = 0; j < 8; j++ )
  {
	D3DXVec3TransformCoord( &indMeshOBBWorldSpace[j], &indMeshBoundsModelSpace[i].corners[j], &IdentityMatrix );
  }
  // And render
  //RenderOOBB(indMeshOBBWorldSpace);
}*/
}
//loads the vertices
void RenderOOBB(D3DXVECTOR3 *cornersInWorldSpace, int ObjNum)
{
D3DXVECTOR3 front[4],back[4];
front[0] = cornersInWorldSpace[0];
front[1] = cornersInWorldSpace[2];
back[2] = cornersInWorldSpace[3];
back[3] = cornersInWorldSpace[1];
front[3] = cornersInWorldSpace[4];
front[2] = cornersInWorldSpace[6];
back[1] = cornersInWorldSpace[7];
back[0] = cornersInWorldSpace[5];
static float (* FrontX)[4] = new float[ObjectQuantity][4];
static float (* FrontY)[4] = new float[ObjectQuantity][4];
static float (* FrontZ)[4] = new float[ObjectQuantity][4];
	static float (* BackX)[4] = new float[ObjectQuantity][4];
static float (* BackY)[4] = new float[ObjectQuantity][4];
static float (* BackZ)[4] = new float[ObjectQuantity][4];
for (int count = 0; count < 4; ++ count)
{
  FrontX[ObjNum][count] = front[count].x;
  FrontY[ObjNum][count] = front[count].y;
  FrontZ[ObjNum][count] = front[count].z;
  BackX[ObjNum][count] = back[count].x;
  BackY[ObjNum][count] = back[count].y;
  BackZ[ObjNum][count] = back[count].z;
}

		CUSTOMVERTEX vertices[] =
{
		 { FrontX[ObjNum][0], FrontY[ObjNum][0], FrontZ[ObjNum][0], D3DCOLOR_XRGB(0, 0, 255), },
		 { FrontX[ObjNum][1], FrontY[ObjNum][1], FrontZ[ObjNum][1], D3DCOLOR_XRGB(0, 0, 255), },
		 { FrontX[ObjNum][2], FrontY[ObjNum][2], FrontZ[ObjNum][2], D3DCOLOR_XRGB(0, 0, 255), },
		 { FrontX[ObjNum][3], FrontY[ObjNum][3], FrontZ[ObjNum][3], D3DCOLOR_XRGB(0, 0, 255), },
		{ BackX[ObjNum][0], BackY[ObjNum][0], BackZ[ObjNum][0], D3DCOLOR_XRGB(0, 0, 255), },
		{ BackX[ObjNum][1], BackY[ObjNum][1], BackZ[ObjNum][1], D3DCOLOR_XRGB(0, 0, 255), },
	   { BackX[ObjNum][2], BackY[ObjNum][2], BackZ[ObjNum][2], D3DCOLOR_XRGB(0, 0, 255), },
	   { BackX[ObjNum][3], BackY[ObjNum][3], BackZ[ObjNum][3], D3DCOLOR_XRGB(0, 0, 255), },
};
	  // lock v_buffer and load the vertices into it
	v_buffer->Lock(0, 0, (void**)&pVoid, 0);
	memcpy(pVoid, vertices, sizeof(vertices));
	v_buffer->Unlock();

//if the last object has been called
if (ObjNum == 3) //array starts from 0 not 1, that's why -1 ;; that was wrong..
{
  for (int count = 1; count < ObjectQuantity; ++ count) //count 1+ because 0 is skeleton, other objects wont collide
	 {
		for (int CountCorner = 0; CountCorner < 4; ++ CountCorner)
	 {
			if (FrontX[SKELE][0] / BackX[3][0] > 0.98 && FrontX[SKELE][0] / BackX[3][0] < 1)
	  {
	   Movement = FALSE;
	  }
	  else
	  {
	   Movement = TRUE;
	  }
	 }
	 }
  FileWrite(FrontX[0][0], FrontX[0][1], FrontX[0][2], FrontX[0][3], FrontX[SKELE][0], FrontX[SKELE][1]);
}
}


Sponsor:

#2 greenvertex   Members   -  Reputation: 510

Like
0Likes
Like

Posted 06 August 2012 - 05:33 PM

Don't mind the collision checks.
The problem basically is that what I'm getting for my bounding box coordinates is junk.
Junk like...
Object 0: 8.83098e-042 0 0
Object 3: 5 14.3369 1.17549e-038


So:

TMeshBounds *indMeshBoundsModelSpace=XAnimator->GetBoundingShapes(ModelID[ObjNum],&minBoundsModelSpace,&maxBoundsModelSpace,&sphereCentreModelSpace,&sphereRadius,&numMesh);

Is returning junk? If not, could you paste particular pieces of code you may think are faulty and why? This is an awful lot to parse through...

#3 ApochPiQ   Moderators   -  Reputation: 14256

Like
0Likes
Like

Posted 06 August 2012 - 05:56 PM

What makes you say these numbers are "junk"?

#4 theo2005   Members   -  Reputation: 114

Like
0Likes
Like

Posted 07 August 2012 - 03:45 AM

What makes you say these numbers are "junk"?


If my objects are positioned at:
void SetObjectCoords ()
{
  TranslateX[SKELE] = 4.0f;
	 TranslateY[SKELE] = 0.2f;
	 TranslateZ[SKELE] = 3.0f;
  TranslateX[FLOOR] = 0.0f;
  TranslateY[FLOOR] = 0.0f;
  TranslateZ[FLOOR] = 0.0f;
  TranslateX[WALL] = 0.0f;
  TranslateY[WALL] = 0.0f;
  TranslateZ[WALL] = 0.0f;
  TranslateX[3] = 5.0f;
  TranslateY[3] = 0.0f;
  TranslateZ[3] = 0.0f;
}

It makes no sense for their max bounds (as the numbers above) to have such values. At least makes no sense for me.

@greenvertex:

These are the parts I think may be faulty:
for (int count = 0; count < ObjectQuantity; ++count)
   {
   D3DXMatrixMultiply(&IdentityMatrix, &matRotateY[count], &matTranslate[count]);
		   // d3ddev->SetTransform(D3DTS_WORLD, &IdentityMatrix);    // set the world transform
   TMeshBounds *indMeshBoundsModelSpace=XAnimator->GetBoundingShapes(ModelID[count],&minBoundsModelSpace,&maxBoundsModelSpace,&sphereCentreModelSpace,&sphereRadius,&numMesh);
There I figured, to get the world matrix, I'd multiply those two matrices like I do when I draw each object:
for (int CountRender = 0;CountRender < ObjectQuantity; ++ CountRender) //draw all the objects despite of which object time calculation is executing
{
 
   D3DXMatrixTranslation(&matTranslate[CountRender], TranslateX[CountRender], TranslateY[CountRender], TranslateZ[CountRender]);
	  XAnimator->Render(ModelID[CountRender], matRotateY[CountRender] * matTranslate[CountRender]  ,(float)timeElapsedSinceLastUpdate[CountRender]);
}

The so called world matrix I got after multiplying, I then use here (which is the most suspicious place imho):
for( int i = 0; i < 8; i++ )
{
  D3DXVec3TransformCoord( &cornersInWorldSpace[i][count], &cornersInModelSpace[i], &IdentityMatrix);
}

I hope that helps..

#5 greenvertex   Members   -  Reputation: 510

Like
0Likes
Like

Posted 07 August 2012 - 01:38 PM

You might want to look at:

for (int count = 0; count < ObjectQuantity; ++count)
   {
   D3DXMatrixMultiply(&IdentityMatrix, &matRotateY[count], &matTranslate[count]);
//...

From what I can gather, IdentityMatrix seems to be the combination of all linear transforms of all models' rotation and translation up to that point. Is that actually what you wanted? Especially considering the call here:

for (int CountRender = 0;CountRender < ObjectQuantity; ++ CountRender) //draw all the objects despite of which object time calculation is executing
{
   D3DXMatrixTranslation(&matTranslate[CountRender], TranslateX[CountRender], TranslateY[CountRender], TranslateZ[CountRender]);
		  XAnimator->Render(ModelID[CountRender], matRotateY[CountRender] * matTranslate[CountRender]  ,(float)timeElapsedSinceLastUpdate[CountRender]);
}

Doesn't appear to be exhibiting that behavior. There it looks as if each world transform is the linear combination of one translation and one rotation matrix.

#6 theo2005   Members   -  Reputation: 114

Like
0Likes
Like

Posted 07 August 2012 - 02:16 PM

From what I can gather, IdentityMatrix seems to be the combination of all linear transforms of all models' rotation and translation up to that point. Is that actually what you wanted? Especially considering the call here:


I changed the code above to:
for (int count = 0; count < ObjectQuantity; ++count)
   {
   D3DXMatrixIdentity(&IdentityMatrix);
   D3DXMatrixMultiply(&IdentityMatrix, &matRotateY[count], &matTranslate[count]);

And the only thing that happened was..

max bound values for two objects (x,y,z) changed from

1.77825e-042  0  0
5  14.3369  1.17549e-038

to...

2.83763e-042  0  0
5  14.3369  1.17549e-038

I hope I addressed the problem you pointed out the correct way. Even though it didn't seemingly contribute to much of an anything except different junk values.

Edited by theo2005, 07 August 2012 - 02:17 PM.


#7 greenvertex   Members   -  Reputation: 510

Like
0Likes
Like

Posted 07 August 2012 - 03:56 PM

Yea that would make IdentityMatrix represent the same combinations as above...

I'll keep looking when I get a chance, hopefully something will turn up.

#8 theo2005   Members   -  Reputation: 114

Like
0Likes
Like

Posted 07 August 2012 - 05:45 PM

Yea that would make IdentityMatrix represent the same combinations as above...

I'll keep looking when I get a chance, hopefully something will turn up.


Thank you

#9 greenvertex   Members   -  Reputation: 510

Like
0Likes
Like

Posted 07 August 2012 - 09:21 PM

Try outputting the value of IdentityMatrix in:

FileWrite(maxBoundsWorldSpace[0].x, maxBoundsWorldSpace[0].y, maxBoundsWorldSpace[0].z,maxBoundsWorldSpace[3].x, maxBoundsWorldSpace[3].y, maxBoundsWorldSpace[3].z);

And post the first set of results. I can't see any problems in that loop with the math. Maybe the matrix is not what it appears. If everything's rendering correctly though via:

XAnimator->Render(ModelID[CountRender], matRotateY[CountRender] * matTranslate[CountRender]  ,(float)timeElapsedSinceLastUpdate[CountRender]);

The IdentityMatrix should also be correct...

#10 theo2005   Members   -  Reputation: 114

Like
0Likes
Like

Posted 08 August 2012 - 02:33 AM

I'm not sure how to output a matrix but since it doesn't seem to let me as a multidimensional array.. I guess something like this.

if (count == 0)
   {
    FileWrite(IdentityMatrix[0], IdentityMatrix[1], IdentityMatrix[2],IdentityMatrix[3], 0, 0);
   }

Result: 1 0 0 0

It is the same for every object (0 - 3)

Edited by theo2005, 08 August 2012 - 02:56 AM.


#11 ApochPiQ   Moderators   -  Reputation: 14256

Like
0Likes
Like

Posted 08 August 2012 - 10:20 AM

Are the values returned from XAnimator->GetBoundingShapes() what you expect? No point in trying to mess with all the matrix math if your inputs aren't what you think they should be.

#12 theo2005   Members   -  Reputation: 114

Like
0Likes
Like

Posted 09 August 2012 - 08:47 AM

Are the values returned from XAnimator->GetBoundingShapes() what you expect? No point in trying to mess with all the matrix math if your inputs aren't what you think they should be.


I don't frankly know what to expect. All I know is that I'm doing exactly what the author of the API is doing except I don't use his debug library (which I don't have) to draw the bounds. I did a number of tests. Supposedly if max bounds of object A is bigger than min bounds of object B, they collide. So I did those kinds of checks and set it to stop movement if it happens to be true. The thing is, my movement stops with any checks I make, except for when I inverse the check (to smaller instead of bigger). I then go to the object in question and bash myself into every wall and the checks don't trigger.

In the full main source code, there are two functions in the complete bottom. I used to use those. The second one I wrote to store the vertex data and draw the bounds myself. Well, the bounds were shifted in one direction, the size of the object (either length or width) was smaller/shorter. Regardless of that, I still did a bunch of checks and after some bull*** I managed to find some checks that made the skele stop when bashing into one wall. Actually, he stopped a meter before the wall from the inside of the object without any parts touching the walls. The only bounds that the function drew correctly were the skeletons.

What I said above, including the fact that those numbers are indeed very strange in my opinion, I deduced that something must be wrong with matrix math or perhaps some fundamental calculations I have there.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS