示例#1
0
__fastcall TActiveFormX::TActiveFormX(TComponent* AOwner) : TActiveForm(AOwner)
{

    // create a new world
    world = new cWorld();

    // set background color
    world->setBackgroundColor(0.0f,0.0f,0.0f);

    // Create a camera
    camera = new cCamera(world);
    world->addChild(camera);

    // Create a light source and attach it to camera
    light = new cLight(world);
    light->setEnabled(true);
    light->setPos(cVector3d(2,1,1));

    // define camera position
    cameraAngleH = 10;
    cameraAngleV = 20;
    cameraDistance = 2.0;
    flagCameraInMotion = false;
    updateCameraPosition();
    camera->setClippingPlanes(0.01, 10.0);

    // create a display for graphic rendering
    viewport = new cViewport(Panel1->Handle, camera, true);
    viewport->setStereoOn(false);

    // create a mesh - we will build a simple cube, and later let the
    // user load 3d models
    object = new cMesh(world);
    world->addChild(object);

    // create a nice little cube
    createCube(object, 0.2);

    // define a material property for this object
    cMaterial material;
    material.m_ambient.set( 0.4, 0.2, 0.2, 1.0 );
    material.m_diffuse.set( 0.8, 0.6, 0.6, 1.0 );
    material.m_specular.set( 0.9, 0.9, 0.9, 1.0 );
    material.setShininess(100);
    material.setStiffness(20 );
    object->m_material = material;

    // update camera position
    updateCameraPosition();

    // don't start the haptics loop yet
    flagSimulationOn = false;
    flagHasExitedSimulation = true;
}
void ofxSplineEditor::update(){
    updateSpline();
    updateSplineFileSystem();
    updateSplinePoint();
    updateCameraPosition();
    editPointIndex.setMax(spline.GetPointNum());
}
示例#3
0
void ofxFPSCamera::update(ofEventArgs&) {
    if (controlsEnabled) {
        if(b_back||b_fwd||b_strafe_left||b_strafe_right||b_strafe_up||b_strafe_down) {
            updateCameraPosition();
        }
        if(b_roll_ccw||b_roll_cw||b_roll_reset||b_yaw_left||b_yaw_right||b_pitch_up||b_pitch_down) {
            updateCameraRoll();
        }
    }
}
示例#4
0
void __fastcall TActiveFormX::Timer1Timer(TObject *Sender)
{
    // update camera position
    updateCameraPosition();

    // render world in display
    if (viewport != NULL)
    {
        viewport->render();
    }
}
示例#5
0
void
updatePlayState(PlayState *playState, GameContext *gameContext, UserInput *userInput,
                GameMemory *gameMemory) {

    updateScrollingBackground(playState->scrollingBackground, gameContext);

    updateCameraPosition(playState, gameContext);

    updateEntities(playState, &playState->entityList, gameContext, userInput, gameMemory);

}
示例#6
0
void frameRender()
{
	// Déplacement de la caméra
	updateCameraPosition();

	// Dessin
	g_pTechnique->GetPassByIndex(0)->Apply(0);
	g_pD3DDevice->Draw(4, 0);

	// Swapbuffer
	g_pSwapChain->Present(0, 0);
}
示例#7
0
void mouseMove(int x, int y)
{
    if (flagCameraInMotion)
    {
        if (mouseButton == GLUT_RIGHT_BUTTON)
        {
            cameraDistance = cameraDistance - 0.01 * (y - mouseY);
        }

        else if (mouseButton == GLUT_LEFT_BUTTON)
        {
            cameraAngleH = cameraAngleH - (x - mouseX);
            cameraAngleV = cameraAngleV + (y - mouseY);
        }
    }

    updateCameraPosition();

    mouseX = x;
    mouseY = y;
}
示例#8
0
// Updates the tileMap with the information in the baseGrid and the gameObjectGrid
void GameMap::step()
{
	// Calculate the first visible tile from the map
	cocos2d::Vec2 origin = cocos2d::Director::getInstance()->getVisibleOrigin();
	// Update camera position
	updateCameraPosition();
	int offset_x = firstVisibleTile_x * tileWidth;
	int offset_y = firstVisibleTile_y * tileHeight;
	// Run through the tileMap and color the sprites according to the baseGrid and gameObjectGrid data
	// Initialize x index of current tile
	int currentTile_x = firstVisibleTile_x;
	for (int x = 0; x < tileMap.size(); ++x) {
		// Initialize y index of current tile
		int currentTile_y = firstVisibleTile_y;
		for (int y = 0; y < tileMap[x].size(); ++y) {

			if (currentTile_x >= baseGrid.size() || currentTile_y >= baseGrid[currentTile_x].size()) {
				tileMap[x][y]->setVisible(false);
			} else if (baseGrid[currentTile_x][currentTile_y] == TileType::stone) {
				tileMap[x][y]->setVisible(true);
				tileMap[x][y]->setColor(stoneColour);
			}
			else if (baseGrid[currentTile_x][currentTile_y] == TileType::dirt) {
				tileMap[x][y]->setVisible(true);
				tileMap[x][y]->setColor(dirtColour);
			}
			else if (gameObjectGrid[currentTile_x][currentTile_y] == nullptr) { // empty
				tileMap[x][y]->setVisible(true);
				tileMap[x][y]->setColor(emptyColour);
			}
			else { // Game Object present
				tileMap[x][y]->setVisible(true);
				tileMap[x][y]->setColor(gameObjectGrid[currentTile_x][currentTile_y]->getColour());
			}

			++currentTile_y;
		}
		++currentTile_x;
	}
}
示例#9
0
void __fastcall TActiveFormX::Panel1MouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{
    if (flagCameraInMotion)
    {
        if (Shift.Contains(ssLeft))
        {
            cameraAngleH = cameraAngleH - (X - mouseX);
            cameraAngleV = cameraAngleV + (Y - mouseY);
        }
        else if (Shift.Contains(ssRight))
        {
            cameraDistance = cameraDistance - 0.01 * (Y - mouseY);
        }

        updateCameraPosition();
    }



    mouseX = X;
    mouseY = Y;  
}
示例#10
0
void initShader()
{
	// Récupération des variables du shader
	g_pMaterialAmbientColorVariable = g_pEffect->GetVariableByName("g_MaterialAmbientColor")->AsVector();
	g_pMaterialDiffuseColorVariable = g_pEffect->GetVariableByName("g_MaterialDiffuseColor")->AsVector();
	g_pMaterialSpecularColorVariable = g_pEffect->GetVariableByName("g_MaterialSpecularColor")->AsVector();
	g_pMaterialShininessVariable = g_pEffect->GetVariableByName("g_MaterialShininess")->AsScalar();
	g_pMaterialReflectivityVariable = g_pEffect->GetVariableByName("g_MaterialReflectivity")->AsScalar();
	g_pMaterialTransmittivityVariable = g_pEffect->GetVariableByName("g_MaterialTransmittivity")->AsScalar();
	g_pMaterialRefractionIndiceVariable = g_pEffect->GetVariableByName("g_MaterialRefractionIndice")->AsScalar();
	g_pSpherePositionVariable = g_pEffect->GetVariableByName("g_SpherePosition")->AsVector();
	g_pSphereRadiusVariable = g_pEffect->GetVariableByName("g_SphereRadius")->AsScalar();
	g_pPlaneNormalVariable = g_pEffect->GetVariableByName("g_PlaneNormal")->AsVector();
	g_pPlaneHeightVariable = g_pEffect->GetVariableByName("g_PlaneHeight")->AsScalar();
	g_pLightPositionVariable = g_pEffect->GetVariableByName("g_LightPosition")->AsVector();
	g_pLightDirectionVariable = g_pEffect->GetVariableByName("g_LightDirection")->AsVector();
	g_pLightColorVariable = g_pEffect->GetVariableByName("g_LightColor")->AsVector();
	g_pLightCosInnerConeVariable = g_pEffect->GetVariableByName("g_LightCosInnerCone")->AsScalar();
	g_pLightCosOuterConeVariable = g_pEffect->GetVariableByName("g_LightCosOuterCone")->AsScalar();
	g_pEyePositionVariable = g_pEffect->GetVariableByName("g_EyePosition")->AsVector();
	g_pLookAtVariable = g_pEffect->GetVariableByName("g_LookAt")->AsVector();
	g_pUpVariable = g_pEffect->GetVariableByName("g_Up")->AsVector();
	g_pRatioVariable = g_pEffect->GetVariableByName("g_Ratio")->AsScalar();
	g_pFovVariable = g_pEffect->GetVariableByName("g_Fov")->AsScalar();

	// Initialisation des variables du shader
	D3DXVECTOR3 materialAmbientColorArray[OBJECT_NUM];
	D3DXVECTOR3 materialDiffuseColorArray[OBJECT_NUM];
	D3DXVECTOR3 materialSpecularColorArray[OBJECT_NUM];
	float materialShininessArray[OBJECT_NUM];
	float materialReflectivityArray[OBJECT_NUM];
	float materialTransmittivityArray[OBJECT_NUM];
	float materialRefractionIndiceArray[OBJECT_NUM];
	D3DXVECTOR3 spherePositionArray[SPHERE_NUM];
	float sphereRadiusArray[SPHERE_NUM];
	D3DXVECTOR3 planeNormalArray[PLANE_NUM];
	float planeHeightArray[PLANE_NUM];
	D3DXVECTOR3 lightPositionArray[LIGHT_NUM];
	D3DXVECTOR3 lightDirectionArray[LIGHT_NUM];
	D3DXVECTOR3 lightColorArray[LIGHT_NUM];
	float lightCosInnerConeArray[LIGHT_NUM];
	float lightCosOuterConeArray[LIGHT_NUM];

	for(int i = 0; i < OBJECT_NUM; i++)
	{
		materialAmbientColorArray[i] = D3DXVECTOR3(0.0f, 0.01f, 0.02f);
		materialDiffuseColorArray[i] = D3DXVECTOR3(0.0f, 0.4f, 0.8f);
		materialSpecularColorArray[i] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
		materialShininessArray[i] = 25.0f;
		materialReflectivityArray[i] = 0.3f;
		materialTransmittivityArray[i] = 0.2f;
		materialRefractionIndiceArray[i] = 1.1f;
	}
	for(int i = 0; i < SPHERE_NUM; i++)
	{
		spherePositionArray[i] = D3DXVECTOR3(3.0f*cos(i*2.0f*PI/SPHERE_NUM), 1.0f, 3.0f*sin(i*2.0f*PI/SPHERE_NUM));
		sphereRadiusArray[i] = 1.0f;
	}
	for(int i = 0; i < PLANE_NUM; i++)
	{
		planeNormalArray[i] = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
		planeHeightArray[i] = 0.0f;
	}
	
	for(int i = 0; i < LIGHT_NUM; i++)
	{
		lightPositionArray[i] = D3DXVECTOR3(-15.0f, 30.0f, 0.0f);
		lightDirectionArray[i] = D3DXVECTOR3(0.4f, -0.6f, 0.0f);
		lightColorArray[i] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
		lightCosInnerConeArray[i] = 0.7f;
		lightCosOuterConeArray[i] = 0.6f;
	}

	g_pMaterialAmbientColorVariable->SetFloatVectorArray((float *) materialAmbientColorArray, 0, OBJECT_NUM);
	g_pMaterialDiffuseColorVariable->SetFloatVectorArray((float *) materialDiffuseColorArray, 0, OBJECT_NUM);
	g_pMaterialSpecularColorVariable->SetFloatVectorArray((float *) materialSpecularColorArray, 0, OBJECT_NUM);
	g_pMaterialShininessVariable->SetFloatArray(materialShininessArray, 0, OBJECT_NUM);
	g_pMaterialReflectivityVariable->SetFloatArray(materialReflectivityArray, 0, OBJECT_NUM);
	g_pMaterialTransmittivityVariable->SetFloatArray(materialTransmittivityArray, 0, OBJECT_NUM);
	g_pMaterialRefractionIndiceVariable->SetFloatArray(materialRefractionIndiceArray, 0, OBJECT_NUM);
	g_pSpherePositionVariable->SetFloatVectorArray((float *) spherePositionArray, 0, SPHERE_NUM);
	g_pSphereRadiusVariable->SetFloatArray(sphereRadiusArray, 0, SPHERE_NUM);
	g_pPlaneNormalVariable->SetFloatVectorArray((float *) planeNormalArray, 0, PLANE_NUM);
	g_pPlaneHeightVariable->SetFloatArray(planeHeightArray, 0, PLANE_NUM);
	g_pLightPositionVariable->SetFloatVectorArray((float *) lightPositionArray, 0, LIGHT_NUM);
	g_pLightDirectionVariable->SetFloatVectorArray((float *) lightDirectionArray, 0, LIGHT_NUM);
	g_pLightColorVariable->SetFloatVectorArray((float *) lightColorArray, 0, LIGHT_NUM);
	g_pLightCosInnerConeVariable->SetFloatArray(lightCosInnerConeArray, 0, LIGHT_NUM);
	g_pLightCosOuterConeVariable->SetFloatArray(lightCosOuterConeArray, 0, LIGHT_NUM);
	
	updateCameraPosition();

	g_pRatioVariable->SetFloat((float)SCREEN_WIDTH/(float)SCREEN_HEIGHT);
	g_pFovVariable->SetFloat(FOV);
}
示例#11
0
/* Updates the viewpoint according to the object being tracked */
static bool camTrackCamera()
{
	PROPULSION_STATS *psPropStats;
	DROID *psDroid;
	bool bFlying = false;

	/* Most importantly - see if the target we're tracking is dead! */
	if(trackingCamera.target->died)
	{
		return(false);
	}

	/* Update the acceleration,velocity and position of the camera for movement */
	updateCameraAcceleration(CAM_ALL);
	updateCameraVelocity(CAM_ALL);
	updateCameraPosition(CAM_ALL);

	/* Update the acceleration,velocity and rotation of the camera for rotation */
	/*	You can track roll as well (z axis) but it makes you ill and looks
		like a flight sim, so for now just pitch and orientation */


	if(trackingCamera.target->type == OBJ_DROID)
	{
		psDroid = (DROID*)trackingCamera.target;
		psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
		if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT)
		{
				bFlying = true;
		}
	}

	if(bRadarAllign || trackingCamera.target->type == OBJ_DROID)
	{
		if(bFlying)
		{
			updateCameraRotationAcceleration(CAM_ALL);
		}
		else
		{
			updateCameraRotationAcceleration(CAM_X_AND_Y);
		}
	}
	if(bFlying)
	{
	 	updateCameraRotationVelocity(CAM_ALL);
		updateCameraRotationPosition(CAM_ALL);
	}
	else
	{
		updateCameraRotationVelocity(CAM_X_AND_Y);
		updateCameraRotationPosition(CAM_X_AND_Y);
	}

	/* Update the position that's now stored in trackingCamera.position */
	player.p.x = trackingCamera.position.x;
	player.p.y = trackingCamera.position.y;
	player.p.z = trackingCamera.position.z;

	/* Update the rotations that're now stored in trackingCamera.rotation */
	player.r.x = trackingCamera.rotation.x;
	player.r.y = trackingCamera.rotation.y;
	player.r.z = trackingCamera.rotation.z;

	/* There's a minimum for this - especially when John's VTOL code lets them land vertically on cliffs */
	if(player.r.x>DEG(360+MAX_PLAYER_X_ANGLE))
  	{
   		player.r.x = DEG(360+MAX_PLAYER_X_ANGLE);
   	}

	/* Clip the position to the edge of the map */
	CheckScrollLimits();

	/* Store away our last update as acceleration and velocity are all fn()/dt */
	trackingCamera.lastUpdate = realTime;
	if(bFullInfo)
	{
		flushConsoleMessages();
		if(trackingCamera.target->type == OBJ_DROID)
		{
			printDroidInfo((DROID*)trackingCamera.target);
		}
	}

	/* Switch off if we're jumping to a new location and we've got there */
	if(getRadarTrackingStatus())
	{
		/*	This will ensure we come to a rest and terminate the tracking
			routine once we're close enough
		*/
		if (trackingCamera.velocity*trackingCamera.velocity + trackingCamera.acceleration*trackingCamera.acceleration < 1.f &&
		    trackingCamera.rotVel*trackingCamera.rotVel     + trackingCamera.rotAccel*trackingCamera.rotAccel         < 1.f)
		{
			setWarCamActive(false);
		}
	}
	return(true);
}
示例#12
0
int main(int argc, char* argv[])
{
    //-----------------------------------------------------------------------
    // INITIALIZATION
    //-----------------------------------------------------------------------

    printf ("\n");
    printf ("-----------------------------------\n");
    printf ("CHAI 3D\n");
    printf ("Demo: 52-GEL-duck\n");
    printf ("Copyright 2003-2010\n");
    printf ("-----------------------------------\n");
    printf ("\n\n");
    printf ("Keyboard Options:\n\n");
    printf ("[1] - Show GEL Skeleton\n");
    printf ("[2] - Hide GEL Skeleton\n");
    printf ("[x] - Exit application\n");
    printf ("\n\n");

    // parse first arg to try and locate resources
    resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1);


    //-----------------------------------------------------------------------
    // 3D - SCENEGRAPH
    //-----------------------------------------------------------------------

    // create a new world.
    world = new cWorld();

    // set the background color of the environment
    // the color is defined by its (R,G,B) components.
    world->setBackgroundColor(0.0, 0.0, 0.0);
    world->setBackgroundColor(1.0, 1.0, 1.0);

    // create a camera and insert it into the virtual world
    camera = new cCamera(world);
    world->addChild(camera);

    // position and oriente the camera
    // define a default position of the camera (described in spherical coordinates)
    cameraAngleH = 0;
    cameraAngleV = 45;
    cameraDistance = 2.5;
    updateCameraPosition();

    // set the near and far clipping planes of the camera
    // anything in front/behind these clipping planes will not be rendered
    camera->setClippingPlanes(0.01, 10.0);

    // enable higher rendering quality because we are displaying transparent objects
    camera->enableMultipassTransparency(true);

    // create a light source and attach it to the camera
    light = new cLight(world);
    camera->addChild(light);                   // attach light to camera
    light->setEnabled(true);                   // enable light source
    light->setPos(cVector3d( 2.0, 0.5, 1.0));  // position the light source
    light->setDir(cVector3d(-2.0, 0.5, 1.0));  // define the direction of the light beam
    light->setDirectionalLight(false);
    light->m_ambient.set(0.5, 0.5, 0.5);
    light->m_diffuse.set(0.7, 0.7, 0.7);
    light->m_specular.set(0.9, 0.9, 0.9);


    //-----------------------------------------------------------------------
    // 2D - WIDGETS
    //-----------------------------------------------------------------------

    // create a 2D bitmap logo
    logo = new cBitmap();

    // add logo to the front plane
    camera->m_front_2Dscene.addChild(logo);

    // load a "chai3d" bitmap image file
	  bool fileload;
    fileload = logo->m_image.loadFromFile(RESOURCE_PATH("resources/images/chai3d.bmp"));
	  if (!fileload)
	  {
		  #if defined(_MSVC)
		  fileload = logo->m_image.loadFromFile("../../../bin/resources/images/chai3d.bmp");
		  #endif
	  }

    // position the logo at the bottom left of the screen (pixel coordinates)
    logo->setPos(10, 10, 0);

    // scale the logo along its horizontal and vertical axis
    logo->setZoomHV(0.4, 0.4);

    // here we replace all black pixels (0,0,0) of the logo bitmap
    // with transparent black pixels (0, 0, 0, 0). This allows us to make
    // the background of the logo look transparent.
    logo->m_image.replace(
                          cColorb(0, 0, 0),      // original RGB color
                          cColorb(0, 0, 0, 0)    // new RGBA color
                          );

    // enable transparency
    logo->enableTransparency(true);


    //-----------------------------------------------------------------------
    // HAPTIC DEVICES / TOOLS
    //-----------------------------------------------------------------------

    // create a haptic device handler
    handler = new cHapticDeviceHandler();

    // get access to the first available haptic device
    handler->getDevice(hapticDevice, 0);

    // retrieve information about the current haptic device
    cHapticDeviceInfo info;
    if (hapticDevice)
    {
        hapticDevice->open();
        info = hapticDevice->getSpecifications();
    }

    // desired workspace radius of the cursor
    cursorWorkspaceRadius = 0.8;

    // read the scale factor between the physical workspace of the haptic
    // device and the virtual workspace defined for the tool
    workspaceScaleFactor = cursorWorkspaceRadius / info.m_workspaceRadius;

    // define a scale factor between the force perceived at the cursor and the
    // forces actually sent to the haptic device
    deviceForceScale = 0.005 * (info.m_maxForceStiffness / workspaceScaleFactor);

    // define a force scale factor for the current haptic device.
    const double FORCE_REFERENCE = 10.0;
    deviceForceScale = info.m_maxForce / FORCE_REFERENCE;

    // create a large sphere that represents the haptic device
    deviceRadius = 0.12;
    device = new cShapeSphere(deviceRadius);
    world->addChild(device);
    device->m_material.m_ambient.set(0.4, 0.4, 0.4, 0.7);
    device->m_material.m_diffuse.set(0.7, 0.7, 0.7, 0.7);
    device->m_material.m_specular.set(1.0, 1.0, 1.0, 0.7);
    device->m_material.setShininess(100);
    stiffness = 40;


    //-----------------------------------------------------------------------
    // COMPOSE THE VIRTUAL SCENE
    //-----------------------------------------------------------------------
    // create a world which supports deformable object
    defWorld = new cGELWorld();
    world->addChild(defWorld);
    world->setPos(-1.5, 0.0, -0.1);
    world->rotate(cVector3d(0,1,0), cDegToRad(30));


    //-----------------------------------------------------------------------
    // COMPOSE THE WATER
    //-----------------------------------------------------------------------
    ground = new cGELMesh(world);
    ground->m_useMassParticleModel = true;
    defWorld->m_gelMeshes.push_back(ground);

    cGELMassParticle::default_mass = 0.010;
    cGELMassParticle::default_kDampingPos = 0.4;
    cGELMassParticle::default_gravity.set(0,0,0);

    int u,v;
    int RESOLUTION = 15;
    double SIZE = 3.5;
    for (v=0; v<RESOLUTION; v++)
    {
        for (u=0; u<RESOLUTION; u++)
        {
            double px, py, tu, tv;

            // compute the position of the vertex
            px = SIZE / (double)RESOLUTION * (double)u - (SIZE/2.0);
            py = SIZE / (double)RESOLUTION * (double)v - (SIZE/2.0);

            // create new vertex
            unsigned int index = ground->newVertex(px, py, level);
            cVertex* vertex = ground->getVertex(index);

            // compute texture coordinate
            tu = (double)u / (double)RESOLUTION;
            tv = (double)v / (double)RESOLUTION;
            vertex->setTexCoord(tu, tv);
            vertex->setColor(cColorf(1.0, 0.0, 0.1));
        }
    }

    ground->buildVertices();

    for (v=0; v<RESOLUTION; v++)
    {
        for (u=0; u<RESOLUTION; u++)
        {
            if ((u == 0) || (v == 0) || (u == (RESOLUTION-1)) || (v == (RESOLUTION-1)))
            {
                // create new vertex
                unsigned int index = ((v + 0) * RESOLUTION) + (u + 0);
                ground->m_gelVertices[index].m_massParticle->m_fixed = true;
            }
        }
    }

    cGELLinearSpring::default_kSpringElongation = 10.0; // [N/m]

    // Create a triangle based map using the above pixels
     for (v=0; v<(RESOLUTION-1); v++)
    {
        for (u=0; u<(RESOLUTION-1); u++)
        {
            // get the indexing numbers of the next four vertices
            unsigned int index00 = ((v + 0) * RESOLUTION) + (u + 0);
            unsigned int index01 = ((v + 0) * RESOLUTION) + (u + 1);
            unsigned int index10 = ((v + 1) * RESOLUTION) + (u + 0);
            unsigned int index11 = ((v + 1) * RESOLUTION) + (u + 1);

            // create two new triangles
            ground->newTriangle(index00, index01, index10);
            ground->newTriangle(index10, index01, index11);

            cGELMassParticle* m0 = ground->m_gelVertices[index00].m_massParticle;
            cGELMassParticle* m1 = ground->m_gelVertices[index01].m_massParticle;
            cGELMassParticle* m2 = ground->m_gelVertices[index10].m_massParticle;

            cGELLinearSpring* spring0 = new cGELLinearSpring(m0, m1);
            cGELLinearSpring* spring1 = new cGELLinearSpring(m0, m2);
            ground->m_linearSprings.push_back(spring0);
            ground->m_linearSprings.push_back(spring1);
        }
    }

    double transparencyLevel = 0.7;
    ground->setUseMaterial(true);
    ground->m_material.m_ambient.set(0.6, 0.6, 0.6, transparencyLevel);
    ground->m_material.m_diffuse.set(0.8, 0.8, 0.8, transparencyLevel);
    ground->m_material.m_specular.set(0.9, 0.9, 0.9, transparencyLevel);
    ground->setTransparencyLevel(transparencyLevel);
    ground->setUseTransparency(true);
    cTexture2D* textureGround = new cTexture2D();
    ground->setTexture(textureGround);
    ground->setUseTexture(true, true);

    fileload = textureGround->loadFromFile(RESOURCE_PATH("resources/images/aqua.bmp"));
    if (!fileload)
    {
        #if defined(_MSVC)
        fileload = textureGround->loadFromFile("../../../bin/resources/images/aqua.bmp" );
        #endif
        if (!fileload)
        {
            printf("Error - 3D Texture failed to load correctly.\n");
            close();
            return (-1);
        }
    }

    //-----------------------------------------------------------------------
    // COMPOSE SOME REFLEXION
    //-----------------------------------------------------------------------

    cGenericObject* reflexion = new cGenericObject();
    world->addChild(reflexion);
    cMatrix3d rot;
    rot.set(1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, -1.0);
    reflexion->setRot(rot);
    reflexion->addChild(defWorld);
    reflexion->setPos(0.0, 0.0, 2.0 * level);
    cGenericObject* reflexionTool = new cGenericObject();
    reflexion->addChild(reflexionTool);
    reflexionTool->addChild(device);
    reflexionTool->setPos(0.0, 0.0, -0.5 * level);

    // Play with thse numbers carefully!
    defWorld->m_integrationTime = 0.001;

    // create a deformable mesh
    defObject = new cGELMesh(world);
    defWorld->m_gelMeshes.push_front(defObject);

    //-----------------------------------------------------------------------
    // BUILD THE DUCK!
    //-----------------------------------------------------------------------

    if (USE_SKELETON_MODEL)
    {
        fileload = createSkeletonMesh(defObject, RESOURCE_PATH("resources/models/ducky/duck-200.off"), RESOURCE_PATH("resources/models/ducky/duck-full.obj"));
	    if (!fileload)
	    {
		    #if defined(_MSVC)
		    fileload = createSkeletonMesh(defObject, "../../../bin/resources/models/ducky/duck-200.off", "../../../bin/resources/models/ducky/duck-full.obj");
            #endif
		    if (!fileload)
		    {
			    printf("Error - 3D Model failed to load correctly.\n");
			    close();
			    return (-1);
		    }
	    }
    }
    else
    {
	    fileload = createTetGenMesh(defObject, RESOURCE_PATH("resources/models/ducky/duck-1200.off"), RESOURCE_PATH("resources/models/ducky/duck-green.obj"));
	    if (!fileload)
	    {
		    #if defined(_MSVC)
		    fileload = createTetGenMesh(defObject, "../../../bin/resources/models/ducky/duck-1200.off", "../../../bin/resources/models/ducky/duck-green.obj");
            #endif
		    if (!fileload)
		    {
			    printf("Error - 3D Model failed to load correctly.\n");
			    close();
			    return (-1);
		    }
	    }
    }

    //-----------------------------------------------------------------------
    // OPEN GL - WINDOW DISPLAY
    //-----------------------------------------------------------------------

    // initialize GLUT
	  glutInit(&argc, argv);

    // retrieve the resolution of the computer display and estimate the position
    // of the GLUT window so that it is located at the center of the screen
    int screenW = glutGet(GLUT_SCREEN_WIDTH);
    int screenH = glutGet(GLUT_SCREEN_HEIGHT);
    int windowPosX = (screenW - WINDOW_SIZE_W) / 2;
    int windowPosY = (screenH - WINDOW_SIZE_H) / 2;

    // initialize the OpenGL GLUT window
    glutInitWindowPosition(windowPosX, windowPosY);
    glutInitWindowSize(WINDOW_SIZE_W, WINDOW_SIZE_H);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow(argv[0]);
    glutMouseFunc(mouseClick);
    glutMotionFunc(mouseMove);
    glutDisplayFunc(updateGraphics);
    glutKeyboardFunc(keySelect);
    glutReshapeFunc(resizeWindow);
    glutSetWindowTitle("CS 268 - Sonny Chan & Francois Conti - March 2009");

    // create a mouse menu (right button)
    glutCreateMenu(menuSelect);
    glutAddMenuEntry("full screen", OPTION_FULLSCREEN);
    glutAddMenuEntry("window display", OPTION_WINDOWDISPLAY);
    glutAddMenuEntry("show skeleton", OPTION_SHOWSKELETON);
    glutAddMenuEntry("hide skeleton", OPTION_HIDESKELETON);
    glutAttachMenu(GLUT_RIGHT_BUTTON);


    //-----------------------------------------------------------------------
    // START SIMULATION
    //-----------------------------------------------------------------------

    // simulation in now running
    simulationRunning = true;

    // create a thread which starts the main haptics rendering loop
    cThread* hapticsThread = new cThread();
    hapticsThread->set(updateHaptics, CHAI_THREAD_PRIORITY_HAPTICS);

    // start the main graphics rendering loop
    glutMainLoop();

    // close everything
    close();

    // exit
    return (0);
}
示例#13
0
文件: 20-map.cpp 项目: jateeq/FYDP
void updateHaptics(void)
{
    // state machine
    const int STATE_IDLE            = 1;
    const int STATE_MODIFY_MAP      = 2;
    const int STATE_MOVE_CAMERA     = 3;
    int state = STATE_IDLE;  

    // current tool position
    cVector3d toolGlobalPos;        // global world coordinates
    cVector3d toolLocalPos;         // local coordinates

    // previous tool position
    cVector3d prevToolGlobalPos;    // global world coordinates
    cVector3d prevToolLocalPos;     // local coordinates

    // main haptic simulation loop
    while(simulationRunning)
    {
        // compute global reference frames for each object
        world->computeGlobalPositions(true);

        // update position and orientation of tool
        tool->updatePose();

        // compute interaction forces
        tool->computeInteractionForces();

        // read user switch
        bool userSwitch = tool->getUserSwitch(0);

        // update tool position
        toolGlobalPos = tool->getDeviceGlobalPos();
        toolLocalPos  = tool->getDeviceLocalPos();

        if ((state == STATE_MOVE_CAMERA) && (!userSwitch))
        {
            state = STATE_IDLE;

            // enable haptic interaction with map
            object->setHapticEnabled(true, true);
        }

        else if (((state == STATE_MODIFY_MAP) && (!userSwitch)) ||
            ((state == STATE_MODIFY_MAP) && (!tool->isInContact(magneticLine))))
        {
            state = STATE_IDLE;

            // disable magnetic line
            magneticLine->setHapticEnabled(false);
            magneticLine->setShowEnabled(false);

            // disable spheres
            sphereA->setShowEnabled(false);
            sphereB->setShowEnabled(false);

            // enable haptic interaction with map
            object->setHapticEnabled(true, true);

            // disable forces
            tool->setForcesOFF();

            // update bounding box (can take a little time)
            object->createAABBCollisionDetector(1.01 * proxyRadius, true, false);
            
            // enable forces again
            tool->setForcesON();
        }

        // user clicks with the mouse
        else if ((state == STATE_IDLE) && (userSwitch))
        {
            // start deforming object
            if (tool->isInContact(object))
            {
                state = STATE_MODIFY_MAP;

                // update position of line
                cVector3d posA = toolGlobalPos;
                posA.z =-0.7;

                cVector3d posB = toolGlobalPos;
                posB.z = 0.7;

                magneticLine->m_pointA = posA;
                magneticLine->m_pointB = posB;

                // update position of spheres
                sphereA->setPos(posA);
                sphereB->setPos(posB);

                // enable spheres
                sphereA->setShowEnabled(true);
                sphereB->setShowEnabled(true);

                // enable magnetic line
                magneticLine->setHapticEnabled(true);
                magneticLine->setShowEnabled(true);

                // disable haptic interaction with map
                object->setHapticEnabled(false, true);
            }

            // start moving camera
            else
            {
                state = STATE_MOVE_CAMERA;
                
                // disable haptic interaction with map
                object->setHapticEnabled(false, true);
            }
        }

        // modify map
        else if (state == STATE_MODIFY_MAP)
        {
            // compute tool offset
            cVector3d offset = toolGlobalPos - prevToolGlobalPos;

            // map offset on z axis
            double offsetHeight = offset.z;

            // apply offset to all vertices through a weighted function
            int numVertices = object->getNumVertices(true);
            for (int i=0; i<numVertices; i++)
            {
                // get next vertex
                cVertex* vertex = object->getVertex(i, true);

                // compute distance between vertex and tool
                cVector3d posTool = tool->getProxyGlobalPos();
                cVector3d posVertex = vertex->getPos();
                double distance = cDistance(posTool, posVertex);

                // compute factor
                double RADIUS = 0.4;
                double relativeDistance = distance / RADIUS;
                double clampedRelativeDistance = cClamp01(relativeDistance);
                double w = 0.5 + 0.5 * cos(clampedRelativeDistance * CHAI_PI);

                // apply offset
                double offsetVertexHeight = w * offsetHeight;
                posVertex.z = posVertex.z + offsetVertexHeight;
                vertex->setPos(posVertex);
            }
        }

        // move camera
        else if (state == STATE_MOVE_CAMERA)
        {
            // compute tool offset
            cVector3d offset = toolLocalPos - prevToolLocalPos;

            // apply camera motion
            cameraDistance = cameraDistance - 2 * offset.x;
            cameraAngleH = cameraAngleH - 40 * offset.y;
            cameraAngleV = cameraAngleV - 40 * offset.z;

            updateCameraPosition();   
        }

        // store tool position
        prevToolLocalPos  = toolLocalPos;
        prevToolGlobalPos = toolGlobalPos;

        // send forces to device
        tool->applyForces();
    }
    
    // exit haptics thread
    simulationFinished = true;
}
示例#14
0
文件: 20-map.cpp 项目: jateeq/FYDP
int main(int argc, char* argv[])
{
    //-----------------------------------------------------------------------
    // INITIALIZATION
    //-----------------------------------------------------------------------

    printf ("\n");
    printf ("-----------------------------------\n");
    printf ("CHAI 3D\n");
    printf ("Demo: 20-map\n");
    printf ("Copyright 2003-2010\n");
    printf ("-----------------------------------\n");
    printf ("\n\n");
    printf ("Instructions:\n\n");
    printf ("- Use left mouse button to rotate camera view. \n");
    printf ("- Use right mouse button to control camera zoom. \n");
    printf ("- Use haptic device and user switch to rotate \n");
    printf ("  camera or deform terrain. \n");
    printf ("\n\n");
    printf ("Keyboard Options:\n\n");
    printf ("[1] - Texture   (ON/OFF)\n");
    printf ("[2] - Wireframe (ON/OFF)\n");
    printf ("[x] - Exit application\n");
    printf ("\n\n");


    // parse first arg to try and locate resources
    resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1);


    //-----------------------------------------------------------------------
    // 3D - SCENEGRAPH
    //-----------------------------------------------------------------------

    // create a new world.
    world = new cWorld();

    // set the background color of the environment
    // the color is defined by its (R,G,B) components.
    world->setBackgroundColor(0.1, 0.1, 0.1);

    // create a camera and insert it into the virtual world
    camera = new cCamera(world);
    world->addChild(camera);

    // define a default position of the camera (described in spherical coordinates)
    cameraAngleH = 0;
    cameraAngleV = 45;
    cameraDistance = 1.8 * MESH_SCALE_SIZE;
    updateCameraPosition();

    // set the near and far clipping planes of the camera
    // anything in front/behind these clipping planes will not be rendered
    camera->setClippingPlanes(0.01, 10.0);

    // create a light source and attach it to the camera
    light = new cLight(world);
    camera->addChild(light);                   // attach light to camera
    light->setEnabled(true);                   // enable light source
    light->setPos(cVector3d( 0.0, 0.3, 0.3));  // position the light source
    light->setDir(cVector3d(-1.0,-0.1, -0.1));  // define the direction of the light beam
    light->m_ambient.set(0.5, 0.5, 0.5);
    light->m_diffuse.set(0.8, 0.8, 0.8);
    light->m_specular.set(1.0, 1.0, 1.0);

    //-----------------------------------------------------------------------
    // 2D - WIDGETS
    //-----------------------------------------------------------------------

    // create a 2D bitmap logo
    logo = new cBitmap();

    // add logo to the front plane
    camera->m_front_2Dscene.addChild(logo);

    // load a "chai3d" bitmap image file
    bool fileload;
    fileload = logo->m_image.loadFromFile(RESOURCE_PATH("resources/images/chai3d.bmp"));
    if (!fileload)
    {
        #if defined(_MSVC)
        fileload = logo->m_image.loadFromFile("../../../bin/resources/images/chai3d.bmp");
        #endif
    }

    // position the logo at the bottom left of the screen (pixel coordinates)
    logo->setPos(10, 10, 0);

    // scale the logo along its horizontal and vertical axis
    logo->setZoomHV(0.4, 0.4);

    // here we replace all black pixels (0,0,0) of the logo bitmap
    // with transparent black pixels (0, 0, 0, 0). This allows us to make
    // the background of the logo look transparent.
    logo->m_image.replace(
                          cColorb(0, 0, 0),      // original RGB color
                          cColorb(0, 0, 0, 0)    // new RGBA color
                          );

    // enable transparency
    logo->enableTransparency(true);


    //-----------------------------------------------------------------------
    // HAPTIC DEVICES / TOOLS
    //-----------------------------------------------------------------------

    // create a haptic device handler
    handler = new cHapticDeviceHandler();

    // get access to the first available haptic device
    cGenericHapticDevice* hapticDevice;
    handler->getDevice(hapticDevice, 0);

    // retrieve information about the current haptic device
    cHapticDeviceInfo info;
    if (hapticDevice)
    {
        info = hapticDevice->getSpecifications();
    }

    // create a 3D tool and add it to the world
    tool = new cGeneric3dofPointer(world);

    // attach tool to camera
    camera->addChild(tool);

    // position tool workspace in front of camera (x-axis of camera reference pointing towards the viewer)
    tool->setPos(-cameraDistance, 0.0, 0.0);

    // connect the haptic device to the tool
    tool->setHapticDevice(hapticDevice);

    // initialize tool by connecting to haptic device
    tool->start();

    // map the physical workspace of the haptic device to a larger virtual workspace.
    tool->setWorkspaceRadius(1.0);

    // define a radius for the tool (graphical display)
    tool->setRadius(0.03);

    // hide the device sphere. only show proxy.
    tool->m_deviceSphere->setShowEnabled(false);

    // set the physical readius of the proxy.
    proxyRadius = 0.0;
    tool->m_proxyPointForceModel->setProxyRadius(proxyRadius);
	tool->m_proxyPointForceModel->m_collisionSettings.m_checkBothSidesOfTriangles = false;


    //-----------------------------------------------------------------------
    // COMPOSE THE VIRTUAL SCENE
    //-----------------------------------------------------------------------
    // create a new mesh to display a height map
    object = new cMesh(world);
    world->addChild(object);

    // load default map
    loadHeightMap();

    // read the scale factor between the physical workspace of the haptic
    // device and the virtual workspace defined for the tool
    double workspaceScaleFactor = tool->getWorkspaceScaleFactor();

    // define a maximum stiffness that can be handled by the current
    // haptic device. The value is scaled to take into account the
    // workspace scale factor
    double stiffnessMax = info.m_maxForceStiffness / workspaceScaleFactor;
    object->setStiffness(0.5 * stiffnessMax, true);

    // create a small vertical white magnetic line that will be activated when the
    // user deforms the mesh.
    magneticLine = new cShapeLine(cVector3d(0,0,0), cVector3d(0,0,0));
    world->addChild(magneticLine);
    magneticLine->m_ColorPointA.set(0.6, 0.6, 0.6);
    magneticLine->m_ColorPointB.set(0.6, 0.6, 0.6);
    magneticLine->setShowEnabled(false);

    // set haptic properties
    magneticLine->m_material.setStiffness(0.05 * stiffnessMax);
    magneticLine->m_material.setMagnetMaxForce(0.2 * info.m_maxForce);
    magneticLine->m_material.setMagnetMaxDistance(0.25);
    magneticLine->m_material.setViscosity(0.05 * info.m_maxLinearDamping);

    // create a haptic magnetic effect
    cEffectMagnet* newEffect = new cEffectMagnet(magneticLine);
    magneticLine->addEffect(newEffect);

    // disable haptic feedback for now
    magneticLine->setHapticEnabled(false);

    // create two sphere that will be added at both ends of the line
    sphereA = new cShapeSphere(0.02);
    sphereB = new cShapeSphere(0.02);
    world->addChild(sphereA);
    world->addChild(sphereB);
    sphereA->setShowEnabled(false);
    sphereB->setShowEnabled(false);

    // define some material properties for spheres
    cMaterial matSphere;
    matSphere.m_ambient.set(0.5, 0.2, 0.2);
    matSphere.m_diffuse.set(0.8, 0.4, 0.4);
    matSphere.m_specular.set(1.0, 1.0, 1.0);
    sphereA->setMaterial(matSphere);
    sphereB->setMaterial(matSphere);


    //-----------------------------------------------------------------------
    // OPEN GL - WINDOW DISPLAY
    //-----------------------------------------------------------------------

    // initialize GLUT
    glutInit(&argc, argv);

    // retrieve the resolution of the computer display and estimate the position
    // of the GLUT window so that it is located at the center of the screen
    int screenW = glutGet(GLUT_SCREEN_WIDTH);
    int screenH = glutGet(GLUT_SCREEN_HEIGHT);
    int windowPosX = (screenW - WINDOW_SIZE_W) / 2;
    int windowPosY = (screenH - WINDOW_SIZE_H) / 2;

    // initialize the OpenGL GLUT window
    glutInitWindowPosition(windowPosX, windowPosY);
    glutInitWindowSize(WINDOW_SIZE_W, WINDOW_SIZE_H);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(updateGraphics);
    glutMouseFunc(mouseClick);
    glutMotionFunc(mouseMove);
    glutKeyboardFunc(keySelect);
    glutReshapeFunc(resizeWindow);
    glutSetWindowTitle("CHAI 3D");


    //-----------------------------------------------------------------------
    // START SIMULATION
    //-----------------------------------------------------------------------

    // simulation in now running
    simulationRunning = true;

    // create a thread which starts the main haptics rendering loop
    cThread* hapticsThread = new cThread();
    hapticsThread->set(updateHaptics, CHAI_THREAD_PRIORITY_HAPTICS);

    // start the main graphics rendering loop
    glutMainLoop();

    // close everything
    close();

    // exit
    return (0);
}
示例#15
0
/* Updates the viewpoint according to the object being tracked */
BOOL	camTrackCamera( void )
{
    PROPULSION_STATS	*psPropStats;
    DROID	*psDroid;
    BOOL	bFlying;

    bFlying = false;

    /* Most importantly - see if the target we're tracking is dead! */
    if(trackingCamera.target->died)
    {
        setFindNewTarget();
        return(false);
    }

    /*	Cancel tracking if it's no longer selected.
    	This may not be desirable? 	*/
    if(trackingCamera.target->type == OBJ_DROID)
    {

//		if(!trackingCamera.target->selected)
//		{
//			return(false);
//		}
    }

    /* Update the acceleration,velocity and position of the camera for movement */
    updateCameraAcceleration(CAM_ALL);
    updateCameraVelocity(CAM_ALL);
    updateCameraPosition(CAM_ALL);

    /* Update the acceleration,velocity and rotation of the camera for rotation */
    /*	You can track roll as well (z axis) but it makes you ill and looks
    	like a flight sim, so for now just pitch and orientation */


    if(trackingCamera.target->type == OBJ_DROID)
    {
        psDroid = (DROID*)trackingCamera.target;
        psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
        if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT)
        {
            bFlying = true;
        }
    }
    /*
    	bIsBuilding = false;
    	if(trackingCamera.target->type == OBJ_DROID)
    	{
    		psDroid= (DROID*)trackingCamera.target;
    		if(DroidIsBuilding(psDroid))
    		{
    			bIsBuilding = true;
    		}
    	}
    */


    if(bRadarAllign || trackingCamera.target->type == OBJ_DROID)
    {
        if(bFlying)
        {
            updateCameraRotationAcceleration(CAM_ALL);
        }
        else
        {
            updateCameraRotationAcceleration(CAM_X_AND_Y);
        }
    }
    if(bFlying)
    {
        updateCameraRotationVelocity(CAM_ALL);
        updateCameraRotationPosition(CAM_ALL);
    }
    /*
    else if(bIsBuilding)
    {
    	updateCameraRotationVelocity(CAM_X_ONLY);
    }
    */
    else
    {
        updateCameraRotationVelocity(CAM_X_AND_Y);
        updateCameraRotationPosition(CAM_X_AND_Y);
    }

    /* Record the old positions for comparison */
    oldPosition.x = player.p.x;
    oldPosition.y = player.p.y;
    oldPosition.z = player.p.z;

    /* Update the position that's now stored in trackingCamera.position */
    player.p.x = trackingCamera.position.x;
    player.p.y = trackingCamera.position.y;
    player.p.z = trackingCamera.position.z;

    /* Record the old positions for comparison */
    oldRotation.x = player.r.x;
    oldRotation.y = player.r.y;
    oldRotation.z = player.r.z;

    /* Update the rotations that're now stored in trackingCamera.rotation */
    player.r.x = trackingCamera.rotation.x;
    /*if(!bIsBuilding)*/
    player.r.y = trackingCamera.rotation.y;
    player.r.z = trackingCamera.rotation.z;

    /* There's a minimum for this - especially when John's VTOL code lets them land vertically on cliffs */
    if(player.r.x>DEG(360+MAX_PLAYER_X_ANGLE))
    {
        player.r.x = DEG(360+MAX_PLAYER_X_ANGLE);
    }

    /*
    if(bIsBuilding)
    {
    	player.r.y+=DEG(1);
    }
    */
    /* Clip the position to the edge of the map */
    CheckScrollLimits();

    /* Store away our last update as acceleration and velocity are all fn()/dt */
    trackingCamera.lastUpdate = gameTime2;
    if(bFullInfo)
    {
        flushConsoleMessages();
        if(trackingCamera.target->type == OBJ_DROID)
        {
            printDroidInfo((DROID*)trackingCamera.target);
        }
    }

    /* Switch off if we're jumping to a new location and we've got there */
    if(getRadarTrackingStatus())
    {
        /*	This will ensure we come to a rest and terminate the tracking
        	routine once we're close enough
        */
        if(getRotationMagnitude()<10000)
        {
            if(getPositionMagnitude() < 60)
            {
                setWarCamActive(false);
            }
        }
    }
    return(true);
}
示例#16
0
bool Visualization::update()
{
    if (!m_initialized)
    {
        printf("Visualization has not been yet initialized.");
        return false;
    }
    
    // Compute the time since last update (in seconds).
    Uint32 time = SDL_GetTicks();
    float dt = (time - m_lastTickCount) / 1000.0f;
    m_lastTickCount = time;
    
    bool singleSimulationStep = false;
    bool scrollForward = false;
    bool scrollBackward = false;
    
    int mscroll = 0;
    
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
            case SDL_KEYDOWN:
                // Handle any key presses here.
                if (event.key.keysym.sym == SDLK_ESCAPE) //Escape.
                {
                    m_stopRequested = true;
                }
                else if (event.key.keysym.sym == SDLK_SPACE)
                {
                    m_paused = !m_paused;
                }
                else if (event.key.keysym.sym == SDLK_TAB)
                {
                    singleSimulationStep = true;
				}
				else if (event.key.keysym.sym == SDLK_r)
				{
					float pos[3] = {-15, 0, 15};
					m_crowd->pushAgentPosition(0, pos);
				}
				else if (event.key.keysym.sym == SDLK_KP7)
				{
					float pos[3] = {-19, 0, -19};
					dtVnormalize(pos);
					dtVscale(pos, pos, 2.f);

					dtCrowdAgent ag;
					m_crowd->fetchAgent(ag, 0);
					dtVcopy(ag.velocity, pos);
					m_crowd->pushAgent(ag);
				}
				else if (event.key.keysym.sym == SDLK_KP9)
				{
					float pos[] = {19, 0, -19};
					dtVnormalize(pos);
					dtVscale(pos, pos, 2.f);

					dtCrowdAgent ag;
					m_crowd->fetchAgent(ag, 0);
					dtVcopy(ag.velocity, pos);
					m_crowd->pushAgent(ag);
				}
				else if (event.key.keysym.sym == SDLK_KP3)
				{
					float pos[3] = {19, 0, 19};
					dtVnormalize(pos);
					dtVscale(pos, pos, 2.f);

					dtCrowdAgent ag;
					m_crowd->fetchAgent(ag, 0);
					dtVcopy(ag.velocity, pos);
					m_crowd->pushAgent(ag);
				}
				else if (event.key.keysym.sym == SDLK_KP1)
				{
					float pos[3] = {-19, 0, 19};
					dtVnormalize(pos);
					dtVscale(pos, pos, 2.f);

					dtCrowdAgent ag;
					m_crowd->fetchAgent(ag, 0);
					dtVcopy(ag.velocity, pos);
					m_crowd->pushAgent(ag);
				}
				else if (event.key.keysym.sym == SDLK_KP5)
				{
					float pos[3] = {0, 0, 0};
					dtVnormalize(pos);
					dtVscale(pos, pos, 2.f);

					dtCrowdAgent ag;
					m_crowd->fetchAgent(ag, 0);
					dtVcopy(ag.velocity, pos);
					m_crowd->pushAgent(ag);
				}
                break;
                
            case SDL_MOUSEBUTTONDOWN:
                if (event.button.button == SDL_BUTTON_RIGHT)
                {
                    // Rotate view
                    m_rotating = true;
                    m_initialMousePosition[0] = m_mousePosition[0];
                    m_initialMousePosition[1] = m_mousePosition[1];
                    m_intialCameraOrientation[0] = m_cameraOrientation[0];
                    m_intialCameraOrientation[1] = m_cameraOrientation[1];
                    m_intialCameraOrientation[2] = m_cameraOrientation[2];
                }	
                else if (event.button.button == SDL_BUTTON_WHEELUP)
                {
                    scrollForward = true;
                }
				else if (event.button.button == SDL_BUTTON_WHEELDOWN)
				{
					scrollBackward = true;
				}
                break;
                
            case SDL_MOUSEBUTTONUP:
                if (event.button.button == SDL_BUTTON_RIGHT)
                {
                    m_rotating = false;
                }
                else if (event.button.button == SDL_BUTTON_LEFT)
                {
                    float pickedPosition[3];
					int index = 0;
                    pick(pickedPosition, &index);
                }
                break;
                
            case SDL_MOUSEMOTION:
                m_mousePosition[0] = event.motion.x;
                m_mousePosition[1] = m_winHeight-1 - event.motion.y;
                if (m_rotating)
                {
                    int dx = m_mousePosition[0] - m_initialMousePosition[0];
                    int dy = m_mousePosition[1] - m_initialMousePosition[1];
                    
                    m_cameraOrientation[0] = m_intialCameraOrientation[0] - dy*0.25f;
                    m_cameraOrientation[1] = m_intialCameraOrientation[1] + dx*0.25f;
                }
                break;
                
            case SDL_QUIT:
                m_stopRequested = true;
                break;
                
            default:
                break;
        }
    }
    
    unsigned char mbut = 0;
    if (SDL_GetMouseState(0,0) & SDL_BUTTON_LMASK)
        mbut |= IMGUI_MBUT_LEFT;
    if (SDL_GetMouseState(0,0) & SDL_BUTTON_RMASK)
        mbut |= IMGUI_MBUT_RIGHT;
    
    // Update the camera velocity from keyboard state.
    Uint8* keystate = SDL_GetKeyState(NULL);
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4800)
#endif
    updateCameraVelocity(
                         dt,
                         keystate[SDLK_w] || keystate[SDLK_UP] || scrollForward,
                         keystate[SDLK_s] || keystate[SDLK_DOWN] || scrollBackward,
                         keystate[SDLK_a] || keystate[SDLK_LEFT],
                         keystate[SDLK_d] || keystate[SDLK_RIGHT],
                         SDL_GetModState() & KMOD_SHIFT);
#ifdef _MSC_VER
#pragma warning(pop)
#endif

    //Update the camera position
    updateCameraPosition(dt);
    
    //Update the crowd
    if (m_crowd)
    {
        if (singleSimulationStep)
        {
            m_paused = true;
            m_debugInfo->startUpdate();

			m_crowd->update(m_crowdDt);

            m_debugInfo->endUpdate(m_crowdDt);
            m_crowdAvailableDt = 0.f;
        }
        else if (!m_paused)
        {
            m_crowdAvailableDt += dt;
            while(m_crowdAvailableDt > m_crowdDt)
            {
				m_debugInfo->startUpdate();

				m_crowd->update(m_crowdDt);

                m_debugInfo->endUpdate(m_crowdDt);
                m_crowdAvailableDt -= m_crowdDt;
            }
        }
        else
        {
            m_crowdAvailableDt = 0.f;
        }
    }
    
    // Set rendering context
    glViewport(0, 0, m_winWidth, m_winHeight);
    glClearColor(0.3f, 0.3f, 0.32f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_TEXTURE_2D);
    
    // Render 3D
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(50.0f, (float)m_winWidth/(float)m_winHeight, m_zNear, m_zFar);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(m_cameraOrientation[0],1,0,0);
    glRotatef(m_cameraOrientation[1],0,1,0);
    glRotatef(m_cameraOrientation[2],0,0,1);
    glTranslatef(-m_cameraPosition[0], -m_cameraPosition[1], -m_cameraPosition[2]);
    
    // Extract OpenGL view properties
    glGetDoublev(GL_PROJECTION_MATRIX, m_projection);
    glGetDoublev(GL_MODELVIEW_MATRIX, m_modelView);
    glGetIntegerv(GL_VIEWPORT, m_viewport);
    
    renderScene();
    renderCrowd();
    
    // Render 2D Overlay
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, m_winWidth, 0, m_winHeight);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
       
    imguiBeginFrame(m_mousePosition[0], m_mousePosition[1], mbut,mscroll);
    
    renderDebugInfoOverlay();
    
    imguiEndFrame();
    imguiRenderGLDraw();		
    
    glEnable(GL_DEPTH_TEST);
    SDL_GL_SwapBuffers();
    
    return true;
}