Return to main.cpp CVS log | Up to Nevrax / code / nel / samples / pacs |
File: Nevrax / code / nel / samples / pacs / main.cpp (download) Revision 1.2, Wed Feb 20 18:07:14 2002 UTC (5 months ago) by lecroart Branch: MAIN CVS Tags: georges_v2, HEAD Changes since 1.1: +2 -2 lines #FIXED: doxygen warning |
/** \file pacs/main.cpp * Pacs sample using user interface. * * $Id: main.cpp,v 1.2 2002/02/20 18:07:14 lecroart Exp $ */ /* Copyright, 2001 Nevrax Ltd. * * This file is part of NEVRAX NEL. * NEVRAX NEL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * NEVRAX NEL is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * You should have received a copy of the GNU General Public License * along with NEVRAX NEL; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ #include "object.h" // Pacs includes #include <nel/pacs/u_move_container.h> #include <nel/pacs/u_move_primitive.h> #include <nel/pacs/u_collision_desc.h> // Misc includes #include <nel/misc/time_nl.h> #include <nel/misc/path.h> // 3d includes #include <nel/3d/u_camera.h> #include <nel/3d/u_driver.h> #include <nel/3d/u_text_context.h> #include <nel/3d/u_instance.h> #include <nel/3d/u_scene.h> #include <nel/3d/u_3d_mouse_listener.h> #include <nel/3d/u_material.h> #ifdef NL_OS_WINDOWS // Just for the main function and ::MessageBox #include <windows.h> #endif // NL_OS_WINDOWS using namespace NLMISC; using namespace NL3D; using namespace NLPACS; // Some defines #define ARENA_SIZE 50 #define NUM_CELL 10 #define SIZE_PRIMITIVE_MIN (1) #define SIZE_PRIMITIVE_MAX 2 #define KEYBOARD_ACCEL (5.0) // m.s-2 #define SHOCK_ABSORB (0.9) // #define DELTA_TIME (0.1) #define GO (10) #define BORDER_SIZE SIZE_PRIMITIVE_MAX #define INIT_SPEED 9 #define MAX_WORLD_IMAGE 31 volatile bool synchro; // Get a random size double randomSize () { return (SIZE_PRIMITIVE_MAX - SIZE_PRIMITIVE_MIN)*((double)rand() / (double)RAND_MAX) + SIZE_PRIMITIVE_MIN; } // Get a random rotation double randomRot () { return 2*(double)Pi*((double)rand() / (double)RAND_MAX); } // Get a random speed CVectorD randomSpeed () { return CVectorD ( 2*(double)INIT_SPEED*((double)rand() / (double)RAND_MAX) - INIT_SPEED, 2*(double)INIT_SPEED*((double)rand() / (double)RAND_MAX) - INIT_SPEED, 0); } // Get a random pos CVectorD randomPos () { return CVectorD ( ((double)ARENA_SIZE - 2*BORDER_SIZE - SIZE_PRIMITIVE_MAX)*((double)rand() / (double)RAND_MAX) - ARENA_SIZE / 2.0 + BORDER_SIZE+ (SIZE_PRIMITIVE_MAX) / 2, ((double)ARENA_SIZE - 2*BORDER_SIZE - SIZE_PRIMITIVE_MAX)*((double)rand() / (double)RAND_MAX) - ARENA_SIZE / 2.0 + BORDER_SIZE+ (SIZE_PRIMITIVE_MAX) / 2, 0); } // Setup speed with keyboard void keyboard (UDriver *pDriver, double deltaTime, CObjectDyn &obj) { // Add speed to selected object CVectorD speed (0,0,0); if (pDriver->AsyncListener.isKeyDown (KeyLEFT)) speed.x+=KEYBOARD_ACCEL*deltaTime; if (pDriver->AsyncListener.isKeyDown (KeyRIGHT)) speed.x-=KEYBOARD_ACCEL*deltaTime; if (pDriver->AsyncListener.isKeyDown (KeyUP)) speed.y-=KEYBOARD_ACCEL*deltaTime; if (pDriver->AsyncListener.isKeyDown (KeyDOWN)) speed.y+=KEYBOARD_ACCEL*deltaTime; if (pDriver->AsyncListener.isKeyDown (KeyPRIOR)) speed.z+=KEYBOARD_ACCEL*deltaTime; if (pDriver->AsyncListener.isKeyDown (KeyNEXT)) speed.z-=KEYBOARD_ACCEL*deltaTime; // Set new speed if (speed.norm() > 0) obj.setSpeed(obj.getSpeed ()+speed); } // ** Main entry #ifdef NL_OS_WINDOWS int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) #else // NL_OS_WINDOWS int main () #endif // NL_OS_WINDOWS { try { // Init search pathes CPath::addSearchPath ("shapes"); // Create a driver UDriver *pDriver=UDriver::createDriver(); // Setup text context pDriver->setDisplay (UDriver::CMode(640, 480, 0)); // Create a scene UScene *pScene=pDriver->createScene(); // Create a container // This container has 31 world images. The first is a static world image, the others are dynamic. // Each frame, the sample eval the collision in the next dynamic world image. // This is to show the multiple world images fonctionnality. UMoveContainer *container=UMoveContainer::createMoveContainer (-ARENA_SIZE/2.0, -ARENA_SIZE/2.0, ARENA_SIZE/2.0, ARENA_SIZE/2.0, NUM_CELL, NUM_CELL, (double)SIZE_PRIMITIVE_MAX*sqrt(2.0), MAX_WORLD_IMAGE ); // Set the world image 0 as static (for borders) container->setAsStatic (0); // Array arena std::vector<CObjectDyn*> arrayArena; // Create an arena with boxes int num_cell=ARENA_SIZE/SIZE_PRIMITIVE_MAX+1; for (int cell=0; cell<num_cell; cell++) { // Create static boxes around the test area arrayArena.push_back (new CObjectDyn (SIZE_PRIMITIVE_MAX, SIZE_PRIMITIVE_MAX, 10*SIZE_PRIMITIVE_MAX, 0, CVectorD (SIZE_PRIMITIVE_MAX*cell-(ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, (ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, 0), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::DoNothing, 0, 1, 0)); arrayArena.push_back (new CObjectDyn (SIZE_PRIMITIVE_MAX, SIZE_PRIMITIVE_MAX, 10*SIZE_PRIMITIVE_MAX, 0, CVectorD (SIZE_PRIMITIVE_MAX*cell-(ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, -(ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, 0), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::DoNothing, 0, 1, 0)); arrayArena.push_back (new CObjectDyn (SIZE_PRIMITIVE_MAX, SIZE_PRIMITIVE_MAX, 10*SIZE_PRIMITIVE_MAX, 0, CVectorD ((ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, SIZE_PRIMITIVE_MAX*cell-(ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, 0), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::DoNothing, 0, 1, 0)); arrayArena.push_back (new CObjectDyn (SIZE_PRIMITIVE_MAX, SIZE_PRIMITIVE_MAX, 10*SIZE_PRIMITIVE_MAX, 0, CVectorD (-(ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, SIZE_PRIMITIVE_MAX*cell-(ARENA_SIZE-SIZE_PRIMITIVE_MAX)/2, 0), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::DoNothing, 0, 1, 0)); } // Setup camera UCamera *pCam=pScene->getCam(); pCam->setTransformMode (UTransformable::DirectMatrix); pCam->setPerspective ((float)Pi/2.f, 1.33f, 0.1f, 1000); // Setup the mouse listener U3dMouseListener *plistener=pDriver->create3dMouseListener (); plistener->setHotSpot (CVectorD (0,0,0)); plistener->setFrustrum (pCam->getFrustum()); plistener->setMatrix (pCam->getMatrix()); plistener->setMouseMode (U3dMouseListener::edit3d); // Array of dynamic objects std::vector<CObjectDyn*> arrayObj; // Create one object arrayObj.push_back ( new CObjectDyn (randomSize (), randomSize (), randomPos (), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::Reflexion, 1, 30, 1)); // Selected object uint selected=0; // Get time TTime lastTime=CTime::getLocalTime (); // Current world image uint worldImage=1; // Color to clear the background CRGBA clearColor; // Main loop while (pDriver->isActive() && (!pDriver->AsyncListener.isKeyPushed (KeyESCAPE))) { // Get the current time TTime newTime=CTime::getLocalTime (); double deltaTime=(double)(uint32)(newTime-lastTime)/1000.0; lastTime=newTime; // Insert objects in press INSERT if (pDriver->AsyncListener.isKeyDown (KeyINSERT)) { // Random cylinder and boxes if (rand()&1) arrayObj.push_back (new CObjectDyn (randomSize(), randomSize(), randomSize(), randomRot(), randomPos (), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::Reflexion, 1, 30, worldImage)); else arrayObj.push_back (new CObjectDyn (randomSize (), randomSize (), randomPos (), CVectorD(0,0,0), true, *container, *pScene, UMovePrimitive::Reflexion, 1, 30, worldImage)); } // Make caos if SPACE pressed if (pDriver->AsyncListener.isKeyDown (KeySPACE)) { for (uint t=0; t<arrayObj.size(); t++) arrayObj[t]->setSpeed (randomSpeed ()); } // Keyboard if (arrayObj.size()) { // Manipulate selected primitive keyboard (pDriver, deltaTime, *(arrayObj[selected])); // Remove a primitive if DELETE pressed if (pDriver->AsyncListener.isKeyDown (KeyDELETE)) { arrayObj[arrayObj.size()-1]->remove (*container, *pScene); arrayObj.resize (arrayObj.size()-1); } // Check selected if (selected>=arrayObj.size()) selected=arrayObj.size()-1; if (selected<0) selected=0; // Change selected object if TAB pressed if (pDriver->AsyncListener.isKeyPushed (KeyTAB)) { selected++; selected%=arrayObj.size(); } } // Move primitives for (uint i=0; i<arrayObj.size(); i++) arrayObj[i]->tryMove (DELTA_TIME, *container, worldImage); // Eval static world image container->evalCollision (DELTA_TIME, 0); // Eval current dynamic world image container->evalCollision (DELTA_TIME, worldImage); // Simulation new position for (i=0; i<arrayObj.size(); i++) arrayObj[i]->doMove (DELTA_TIME, worldImage); // Check triggers clearColor=CRGBA::Black; if (container->getNumTriggerInfo()) { // White if collision clearColor=CRGBA (100,100,100); } // Setup view matrix int size=arrayObj.size(); if (size) { // Setup hotspot for the 3d listener plistener->setHotSpot (arrayObj[selected]->getPos()); // Look at selected primitive pCam->lookAt (plistener->getViewMatrix().getPos (), arrayObj[selected]->getPos()); } // Force listener current matrix plistener->setMatrix (pCam->getMatrix()); // Clear pDriver->clearBuffers (clearColor); // Render pScene->render (); // Draw some lines pDriver->setMatrixMode3D(*pCam); // Swap pDriver->swapBuffers (); // Pump messages pDriver->EventServer.pump(); // Next world image int nextImage=worldImage+1; if (nextImage>=MAX_WORLD_IMAGE) nextImage=1; container->duplicateWorldImage (worldImage, nextImage); worldImage=nextImage; } // Remove mouse listener pDriver->delete3dMouseListener (plistener); } catch (Exception& e) { #ifdef NL_OS_WINDOWS ::MessageBox (NULL, e.what(), "Test collision move", MB_OK|MB_ICONEXCLAMATION); #else // NL_OS_WINDOWS printf (e.what()); #endif // NL_OS_WINDOWS } return 0; }