예제 #1
0
//TODO:  Currently this function ONLY supports threading.  Setting it to anything other than the defaults will crash the program.
void GHavok::SetupHavokEngine(bool bUseThreading, int nThreads) {

    if(_bCreated) {
        WriteToLog("WARNING: SetupHavokEngine called more than once.\n");
        return;
    }
    WriteToLog("SetupHavokEngine()\n");
    WriteToLog("   - Use Threading? %d\n",bUseThreading);
    WriteToLog("   - N. Threads: %d\n",nThreads);

    _nThreads = nThreads;
    _bThreaded = bUseThreading;

    WriteToLog("   - Allocating memory manager and thread memory....");
    // Initialize the base system including our memory system
    _memoryManager = new hkPoolMemory();
    _threadMemory = new hkThreadMemory(_memoryManager, 16);

    hkBaseSystem::init( _memoryManager, _threadMemory, errorReport );
    _memoryManager->removeReference();

    WriteToLog("Complete.\n");

    WriteToLog("   - Initializing stack...");
    // We now initialize the stack area to 100k (fast temporary memory to be used by the engine).
    {
        int stackSize = 0x100000;
        _stackBuffer = hkAllocate<char>( stackSize, HK_MEMORY_CLASS_BASE);
        hkThreadMemory::getInstance().setStackArea( _stackBuffer, stackSize);
    }
    WriteToLog("Complete\n");

    {

        WriteToLog("   - Creating physics world...");
        // Create the physics world
        {
            // The world cinfo contains global simulation parameters, including gravity, solver settings etc.
            hkpWorldCinfo worldInfo;

            // Set the simulation type of the world to multi-threaded.
            worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;
            worldInfo.m_collisionTolerance = 0.03f;	//TODO: Make this a class variable
            _physicsWorld = new hkpWorld(worldInfo);
        }
        WriteToLog("Complete\n");

        WriteToLog("   - Preallocating havok memory blocks...");

        //
        // Pre-allocate some larger memory blocks. These are used by the physics system when in multithreaded mode
        // The amount and size of these depends on your physics usage.  Larger simulation islands will use larger memory blocks.
        //
        {
            hkMemory::getInstance().preAllocateRuntimeBlock(512000, HK_MEMORY_CLASS_BASE);
            hkMemory::getInstance().preAllocateRuntimeBlock(256000, HK_MEMORY_CLASS_BASE);
            hkMemory::getInstance().preAllocateRuntimeBlock(128000, HK_MEMORY_CLASS_BASE);
            hkMemory::getInstance().preAllocateRuntimeBlock(64000, HK_MEMORY_CLASS_BASE);
            hkMemory::getInstance().preAllocateRuntimeBlock(32000, HK_MEMORY_CLASS_BASE);
            hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);
            hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);
        }
        WriteToLog("Complete.\n");

        //
        // When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks
        // to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread
        // must call markForRead / markForWrite before it modifies the world to enable these checks.
        //

        _physicsWorld->markForWrite();

        //
        // Register all collision agents, even though only box - box will be used in this particular example.
        // It's important to register collision agents before adding any entities to the world.
        //
        WriteToLog("   - Registering agents...");
        {
            hkpAgentRegisterUtil::registerAllAgents( _physicsWorld->getCollisionDispatcher() );
        }
        WriteToLog("Complete.\n");

        //
        // Create a multi-threading utility.  This utility will create a number of threads that will run the
        // physics step in parallel. The main thread calls functions in the utility which signal these threads
        // to start a new step, or wait for step completion.
        //

        WriteToLog("   - Creating multi-threaded environment...");
        hkpMultithreadingUtilCinfo info;
        info.m_world = _physicsWorld;
        info.m_numThreads = _nThreads;

        // In this example we enable timers. The multi-threading util will allocate a buffer per thread for capturing timer data.
        // If you leave this flag to false, no timers will be enabled.
        info.m_enableTimers = true;
        _multithreadingUtil = new hkpMultithreadingUtil(info);
        WriteToLog("Complete.\n");

        // Create all the physics rigid bodies
        //SetupPhysicsWorld( physicsWorld );

        //
        // Initialize the visual debugger so we can connect remotely to the simulation
        // The context must exist beyond the use of the VDB instance, and you can make
        // whatever contexts you like for your own viewer types.
        //

        WriteToLog("   - Initializing visual debugger...");
        _context = new hkpPhysicsContext();
        hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers
        _context->addWorld(_physicsWorld); // add the physics world so the viewers can see it

        _hkVis = SetupVisualDebugger();

        _context->m_monitorStreamBegins.setSize(_nThreads);
        _context->m_monitorStreamEnds.setSize(_nThreads);
        WriteToLog("Complete\n");

        // Now we have finished modifying the world, release our write marker.
        _physicsWorld->unmarkForWrite();
    }
    _bCreated = true;
    WriteToLog("\nSetupHavokEngine() succeeded.\n");

}
예제 #2
0
void CurrentApp::LoadContent()
{
	// setup gpass framebuffer
	m_gPassTarget = new RenderTarget();
	m_gPassTarget->SetSize(1280, 720);
	m_gPassTarget->Initialise();
	m_gPassTarget->AttachColourBuffer(0, GL_RGB8); //albedo
	m_gPassTarget->AttachColourBuffer(1, GL_RGB32F); //position
	m_gPassTarget->AttachColourBuffer(2, GL_RGB32F); //normal
	m_gPassTarget->AttachDepthBuffer();
	m_gPassTarget->SetDrawBuffers();

	// setup light framebuffer
	m_lightPassTarget = new RenderTarget();
	m_lightPassTarget->SetSize(1280, 720);
	m_lightPassTarget->Initialise();
	m_lightPassTarget->AttachColourBuffer(0, GL_RGB8);
	m_lightPassTarget->AttachDepthBuffer();
	m_lightPassTarget->SetDrawBuffers();

	CreateFullscreenQuad();

	//Setting up Physx
	m_gravity = -9.8f;
	SetupPhysx();
	SetupVisualDebugger();

	//Set up a Player
	g_ControllerManager = PxCreateControllerManager(*g_PhysicsScene);
	PxCapsuleControllerDesc desc;
	desc.contactOffset = 0.05f;
	desc.height = 3.0f;
	desc.material = g_PhysicsMaterial;
	desc.nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING_AND_FORCE_SLIDING;
	desc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED;
	desc.position = PxExtendedVec3(100, 200, 150);
	desc.radius = 2.0f;
	desc.stepOffset = 0.1f;
	g_PlayerCollisions = new PlayerCollisions();
	desc.reportCallback = g_PlayerCollisions;
	g_PlayerController = g_ControllerManager->createController(desc);

	//Create a New Camera
	m_camera = new FlyCamera();
	m_camera->SetupProjection(glm::pi<float>() * 0.25f, 16 / 9.f, 0.1f, 10000.f);
	m_camera->LookAt(vec3(100, 10, 10), vec3(0), vec3(0, 1, 0));

	m_assetManager = new AssetManager();

	m_renderer = new Renderer(m_assetManager);

	//Terrain Shit here
	m_terrain = m_renderer->CreateTerrain();
	m_terrain->SetSize(30, 30);
	m_terrain->GenerateFromPerlin();

	m_nodeMap = new NodeMap();
	m_nodeMap->GenerateFromTerrain(m_terrain);

	////Snow Particle
	m_snowEmitter = m_renderer->CreateParticle();
	m_snowEmitter->ReadFile("./Content/Particles/Rain");
	//m_snowEmitter->UseTexture("./Content/Particles/ROBOTUNICORN.png");
	m_snowEmitter->SetPosition(glm::vec3(150, 400, 150));
	m_snowEmitter->initalise("");

	m_fairyEmitter = m_renderer->CreateParticle();
	m_fairyEmitter->ReadFile("./Content/Particles/fairy");
	m_fairyEmitter->SetPosition(glm::vec3(100, 130, 100));
	m_fairyEmitter->initalise("");

	//Load Renderables
	int cubeModel = m_assetManager->LoadModel("./Content/Renderables/cube.fbx");
	int sphereModel = m_assetManager->LoadModel("./Content/Renderables/cube.fbx");
	int bunnyModel = m_assetManager->LoadModel("./Content/Renderables/bunny.fbx");
	int treeModel = m_assetManager->LoadModel("./Content/Renderables/Tree/AlanTree.fbx");
	//m_assetManager->RecalculateNormals(treeModel);

	//LoadSkybox
	m_skybox = new Skybox(); 

	std::vector<std::string> faces;

	faces.push_back("./Content/Textures/skyRight.png");
	faces.push_back("./Content/Textures/skyLeft.png");
	faces.push_back("./Content/Textures/skyTop.png");
	faces.push_back("./Content/Textures/skyBottom.png");
	faces.push_back("./Content/Textures/skyFront.png");
	faces.push_back("./Content/Textures/skyBack.png");

	m_skybox->Initialize(faces);

	//Load AI
	m_world = new World(m_nodeMap);

	//Load Lights
	m_light = m_renderer->CreateLight();
	m_light->SetColour(glm::vec4(200, 255, 255, 1));
	m_light->SetFallOff(200000);
	m_light->SetPosition(glm::vec3(150, 30, 150));

	m_sunLight = m_renderer->CreateLight();
	m_sunLight->SetColour(glm::vec4(50, 50, 80, 1));
	m_sunLight->SetFallOff(1000000);
	m_sunLight->SetPosition(glm::vec3(0, 200, 0));

	//create our particle system
	PxParticleFluid* pf;
	// create particle system in PhysX SDK
	// set immutable properties.
	PxU32 maxParticles = 200;
	bool perParticleRestOffset = false;
	pf = g_Physics->createParticleFluid(maxParticles, perParticleRestOffset);
	pf->setRestParticleDistance(3.0f);
	pf->setDynamicFriction(0);
	pf->setStaticFriction(0);
	pf->setDamping(0);
	pf->setParticleMass(30);
	pf->setRestitution(0);
	//pf->setParticleReadDataFlag(PxParticleReadDataFlag::eDENSITY_BUFFER,
	// true);
	pf->setParticleBaseFlag(PxParticleBaseFlag::eCOLLISION_TWOWAY, true);
	pf->setStiffness(300);
	if (pf)
	{
		float multiplier = 10.0f;

		g_PhysicsScene->addActor(*pf);
		m_particleEmitter = new ParticleFluidEmitter(maxParticles, PxVec3(150, 120, 150), pf, .05f);
		m_particleEmitter->setStartVelocityRange(-0.001f, -6000.0f * multiplier, -0.001f, 0.001f, -6000.0f * multiplier, 0.001f);
	}

	for (int i = 0; i < 5; ++i)
	{
		m_AI[i] = new UtilityAI(m_assetManager, m_world, m_nodeMap);
		Renderable* renderBox = m_renderer->CreateRenderable();
		renderBox->SetModel(bunnyModel);
		renderBox->SetScale(glm::vec3(0.01f, 0.01f, 0.01f));
		renderBox->SetTexture(LoadTexture("./Content/Renderables/white.png"));
		m_AI[i]->SetRenderable(renderBox);
	}

	for (int i = 0; i < 50; ++i)
	{
		m_trees[i] = m_renderer->CreateRenderable();
		m_trees[i]->SetModel(treeModel);

		glm::vec3 position = m_nodeMap->GetClosestNode(glm::vec3(40 + rand() % 220, 40 + rand() % 220, 40 + rand() % 220))->GetPos();
		position.y -= 1;
		m_trees[i]->SetPosition(position);

		m_trees[i]->Rotate(glm::vec3(1, 0, 0), -(3.14159265f / 2.0f));
		m_trees[i]->Rotate(glm::vec3(0, 0, 1), rand() % 200 / 100.0f);

		float randVal = rand() % 120 / 120.f;
		m_trees[i]->SetScale(glm::vec3(0.2f + randVal, 0.2f + randVal, 0.2f + randVal));
	}
	
	//Define a Plane
	PxTransform pose = PxTransform(PxVec3(0.0f, 5, 0.0f), PxQuat(PxHalfPi*1.0f, PxVec3(0.0f, 0.0f, 1.0f)));
	PxRigidStatic* plane = PxCreateStatic(*g_Physics, pose, PxPlaneGeometry(), *g_PhysicsMaterial);

	//Add the plane to the Physx Scene
	g_PhysicsScene->addActor(*plane);
	m_terrain->AddPhysicsShape(g_PhysicsScene, g_Physics);

	//Disable the mouse
	SetCursorPos(0, 0);
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}