Ejemplo n.º 1
0
MY_Scene::MY_Scene(Game * _game) :
	Scene(_game),
	screenSurfaceShader(new Shader("assets/RenderSurface", false, true)),
	screenSurface(new RenderSurface(screenSurfaceShader)),
	screenFBO(new StandardFrameBuffer(true)),
	baseShader(new ComponentShaderBase(true)),
	textShader(new ComponentShaderText(true)),
	uiLayer(0,0,0,0),
	bounds(10),
	bulletWorld(new BulletWorld()),
	score(0),
	accuracy(3.f)
{
	baseShader->addComponent(new ShaderComponentMVP(baseShader));
	//baseShader->addComponent(new ShaderComponentDiffuse(baseShader));
	baseShader->addComponent(new ShaderComponentTexture(baseShader));
	baseShader->compileShader();

	textShader->textComponent->setColor(glm::vec3(0.0f, 64.f/255.f, 165.f/255.f));
	
	screenSurface->setScaleMode(GL_NEAREST);

	// remove initial camera
	childTransform->removeChild(cameras.at(0)->parents.at(0));
	delete cameras.at(0)->parents.at(0);
	cameras.pop_back();
	

	// reference counting for member variables
	++baseShader->referenceCount;
	++textShader->referenceCount;

	++screenSurface->referenceCount;
	++screenSurfaceShader->referenceCount;
	++screenFBO->referenceCount;

	float floorL = 1000, floorW = 1000;

	// create floor/ceiling as static bullet planes
	bulletFloor = new BulletMeshEntity(bulletWorld, MeshFactory::getPlaneMesh(), baseShader);
	bulletFloor->setColliderAsStaticPlane(0, 1, 0, 0);
	bulletFloor->createRigidBody(0);
	bulletFloor->body->setFriction(0);
	childTransform->addChild(bulletFloor);
	bulletFloor->meshTransform->scale(-floorL, floorW, 1.f);
	bulletFloor->meshTransform->rotate(-90, 1, 0, 0, kOBJECT);
	bulletFloor->body->getWorldTransform().setRotation(btQuaternion(btVector3(0, 1, 0), glm::radians(180.f)));
	//bulletFloor->mesh->setScaleMode(GL_NEAREST);
	bulletFloor->mesh->scaleModeMag = GL_NEAREST;
	bulletFloor->mesh->scaleModeMin = GL_LINEAR;
	bulletFloor->mesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("CLOUDS")->texture);
	// adjust UVs so that the texture tiles in squares
	for(Vertex & v : bulletFloor->mesh->vertices){
		v.u *= 30.f;
		v.v *= 30.f;
	}



	// car
	TriMesh * shipMesh = MY_ResourceManager::scenario->getMesh("SHIP")->meshes.at(0);
	ship = new BulletMeshEntity(bulletWorld, shipMesh, baseShader);
	childTransform->addChild(ship);
	ship->mesh->setScaleMode(GL_NEAREST);
	ship->mesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("SHIP")->texture);

	ship->setColliderAsBoundingBox();
	ship->createRigidBody(10);
	
	ship->body->setLinearFactor(btVector3(1, 1, 0));
	ship->body->setAngularFactor(btVector3(0, 0, 0));

	ship->maxVelocity = btVector3(10, 10, 0);

	ship->body->setActivationState(4); // always active
	ship->translatePhysical(glm::vec3(0, 10, 0));
	
	//Set up player camera
	zoom = 3.f;
	playerCam = new PerspectiveCamera();
	cameras.push_back(playerCam);
	ship->meshTransform->addChild(playerCam);
	playerCam->nearClip = 0.01f;
	playerCam->farClip = 1000.f;
	playerCam->childTransform->rotate(90, 0, 1, 0, kWORLD);
	playerCam->firstParent()->translate(0, 1.5f, zoom, false);
	playerCam->yaw = 90.0f;
	playerCam->pitch = -10.0f;
	activeCamera = playerCam;

	shipAngle = 0;

	MeshInterface * sphereMesh = MY_ResourceManager::scenario->getMesh("SPHERE")->meshes.at(0);
	sphereMesh->setScaleMode(GL_NEAREST);
	sphereMesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("TRAIL")->texture);

	MeshInterface * ringMesh = MY_ResourceManager::scenario->getMesh("RING")->meshes.at(0);
	ringMesh->setScaleMode(GL_NEAREST);
	ringMesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("RING")->texture);

	trailTimeout = new Timeout(0.05f, [this, sphereMesh](sweet::Event * _event){
		// add player trail
		BulletMeshEntity * t = new BulletMeshEntity(bulletWorld, sphereMesh, baseShader);
		t->setColliderAsBoundingSphere();
		t->createRigidBody(1, 0, 0);
		childTransform->addChild(t);
		trail.push_back(t);
		t->translatePhysical(ship->meshTransform->getWorldPos(), false);
		t->childTransform->scale(sweet::NumberUtils::randomFloat(1,3));
		t->meshTransform->rotate(sweet::NumberUtils::randomFloat(0, 360), 0, 0, 1, kOBJECT);
		t->body->applyCentralImpulse(btVector3(sweet::NumberUtils::randomFloat(-3,3), sweet::NumberUtils::randomFloat(-3,3), sweet::NumberUtils::randomFloat(-3,3) + 10));
		trailTimeout->restart();
	});
	trailTimeout->start();
	//childTransform->addChild(trailTimeout);

	
	obstacleTimeout = new Timeout(0.5f, [this, ringMesh](sweet::Event * _event){
		// add player trail
		BulletMeshEntity * t = new BulletMeshEntity(bulletWorld, ringMesh, baseShader);
		t->setColliderAsBoundingSphere();
		t->createRigidBody(0, 0, 0);
		childTransform->addChild(t);
		obstacles.push_back(t);
		t->translatePhysical(glm::vec3(sweet::NumberUtils::randomFloat(-bounds,bounds)*0.5, sweet::NumberUtils::randomFloat(bounds*0.2,bounds*0.8), -300), false);
		t->meshTransform->rotate(sweet::NumberUtils::randomFloat(0, 360), 0, 0, 1, kOBJECT);
		t->body->setActivationState(4); // always active
		obstacleTimeout->restart();
	});
	obstacleTimeout->start();
	//childTransform->addChild(obstacleTimeout);

	VerticalLinearLayout * vl = new VerticalLinearLayout(uiLayer.world);
	vl->setRationalHeight(1.0f);
	vl->setRationalWidth(1.f);
	vl->setMarginTop(0.1f);
	vl->setRenderMode(kTEXTURE);
	vl->verticalAlignment = kTOP;


	scoreIndicator = new TextLabel(uiLayer.world, MY_ResourceManager::scenario->getFont("FONT")->font, textShader, 1.f);
	scoreIndicator->horizontalAlignment = kCENTER;
	scoreIndicator->setText("SCORE: 0");
	scoreIndicator->invalidateLayout();

	vl->addChild(scoreIndicator);
	uiLayer.addChild(vl);



	MY_ResourceManager::scenario->getAudio("BGM")->sound->play(true);
}
MY_Scene_Main::MY_Scene_Main(Game * _game) :
	MY_Scene_Base(_game),
	bulletWorld(new BulletWorld(glm::vec3(0, -9.8, 0.1))),
	bulletDebugDrawer(new BulletDebugDrawer(bulletWorld->world)),
	indicatorShader(new ComponentShaderBase(true)),
	maskComponentIndicator(nullptr),
	mirrorShader(new ComponentShaderBase(true)),
	vrCam(new StereoCamera()),


	currentTrack(nullptr),
	currentTrackId(-1),

	screenSurfaceShader(new Shader("assets/engine basics/DefaultRenderSurface", false, true)),
	screenSurface(new RenderSurface(screenSurfaceShader, true)),
	screenFBO(new StandardFrameBuffer(true)),
	
	paletteDefIdx(-1),
	
	waitingForInput(false),
	currentHoverTarget(nullptr),
	hoverTime(0),
	targetHoverTime(1.f),

	eventManager(new sweet::EventManager()),
	done(false)
{

	indicatorShader->addComponent(new ShaderComponentMVP(indicatorShader));	
	indicatorShader->addComponent(new ShaderComponentTexture(indicatorShader, 0.1f));
	maskComponentIndicator = new ShaderComponentCircularMask(indicatorShader, 0.1);
	indicatorShader->addComponent(maskComponentIndicator);
	indicatorShader->compileShader();
	indicatorShader->incrementReferenceCount();

	mirrorShader->addComponent(new ShaderComponentMVP(mirrorShader));
	mirrorShader->addComponent(new ShaderComponentTexture(mirrorShader, 0.1f));
	mirrorShader->addComponent(mirrorBlur = new ShaderComponentBlur(mirrorShader));
	mirrorShader->compileShader();
	mirrorShader->incrementReferenceCount();

	// Setup the debug drawer and add it to the scene
	bulletWorld->world->setDebugDrawer(bulletDebugDrawer);
	childTransform->addChild(bulletDebugDrawer, false);
	bulletDebugDrawer->setDebugMode(btIDebugDraw::DBG_NoDebug);


	MeshInterface * chairMesh = MY_ResourceManager::globalAssets->getMesh("chair")->meshes.at(0);
	chairMesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("chair")->texture);
	chairMesh->setScaleMode(GL_NEAREST);

	for(signed long int i = -1; i <= 1; ++i){
		MeshEntity * chair = new MeshEntity(chairMesh, baseShader);
		childTransform->addChild(chair)->translate(glm::vec3(i * 3, 0, 0));
	}
	
	
	std::vector<TriMesh *> environmentMeshes = MY_ResourceManager::globalAssets->getMesh("salon-environment")->meshes;
	std::vector<TriMesh *> propMeshes = MY_ResourceManager::globalAssets->getMesh("salon-props")->meshes;
	std::vector<std::string> environmentMeshOrder;
	environmentMeshOrder.push_back("floor");
	environmentMeshOrder.push_back("walls");
	environmentMeshOrder.push_back("ceiling");
	environmentMeshOrder.push_back("storefront");
	environmentMeshOrder.push_back("door");
	environmentMeshOrder.push_back("windows");
	environmentMeshOrder.push_back("road");
	environmentMeshOrder.push_back("buildings");
	environmentMeshOrder.push_back("sidewalk");

	std::vector<glm::vec3> propMeshOrder;
	propMeshOrder.push_back(glm::vec3(1, 0.96, 0));
	propMeshOrder.push_back(glm::vec3(0.8, 0.45, 0.45));
	propMeshOrder.push_back(glm::vec3(0.5, 0.05, 0.2));
	propMeshOrder.push_back(glm::vec3(1,1,1));
	propMeshOrder.push_back(glm::vec3(0.02, 0.6, 0));
	propMeshOrder.push_back(glm::vec3(0.4, 0.9, 0.9));
	
	for(unsigned long int i = 0; i < environmentMeshes.size(); ++i){
		MeshEntity * c = new MeshEntity(environmentMeshes.at(i), baseShader);
		c->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("salon-" + environmentMeshOrder.at(i))->texture);
		c->mesh->setScaleMode(GL_NEAREST);
		childTransform->addChild(c, false);
	}
	for(unsigned long int i = 0; i < propMeshes.size(); ++i){
		MeshEntity * c = new MeshEntity(propMeshes.at(i), baseShader);
		for(auto & v : c->mesh->vertices){
			v.red = propMeshOrder.at(i).r;
			v.green = propMeshOrder.at(i).g;
			v.blue = propMeshOrder.at(i).b;
		}
		c->mesh->setScaleMode(GL_NEAREST);
		childTransform->addChild(c, false);
	}


	activeCamera = vrCam;
	cameras.push_back(vrCam);
	vrCam->yaw = -90;
	vrCam->nearClip = 0.001f;
	vrCam->fieldOfView = 110;

	avatar = new MY_Avatar(baseShader, vrCam);
	childTransform->addChild(avatar);
	avatar->head->childTransform->addChild(vrCam)->translate(0, 0.5f, 0);

	/*MeshEntity * test = new MeshEntity(Resource::loadMeshFromObj("assets/meshes/buttman.obj", true).at(0), baseShader);
	Texture * tex = new Texture("assets/textures/buttman.png", false, true, true);
	tex->load();
	test->mesh->pushTexture2D(tex);
	childTransform->addChild(test)->translate(0, 3, 2)->rotate(90, 0, 1, 0, kOBJECT);*/
	

	
	/*MY_SelectionTarget * palette = new MY_SelectionTarget(bulletWorld, MY_ResourceManager::globalAssets->getMesh("palette")->meshes.at(0), baseShader);
	palette->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("palette")->texture);
	childTransform->addChild(palette);
	palette->setColliderAsBoundingBox();
	//palette->setColliderAsSphere(5);
	palette->createRigidBody(0);
	palette->translatePhysical(glm::vec3(0, 3, 2));
	palette->name = "test";*/
	//palette->rotatePhysical(90, 0, 1, 0, kOBJECT);
	
	CameraController * c = new CameraController(vrCam);
	c->movementSpeed = 0.05f;
	vrCam->childTransform->addChild(c, false);

	std::vector<glm::vec2> points;
	std::string json = sweet::FileUtils::readFile("assets/path.json");
	Json::Reader reader;
	Json::Value path;
	bool parsingSuccessful = reader.parse( json, path);
	if(!parsingSuccessful){
		Log::error("JSON parse failed: " + reader.getFormattedErrorMessages());
	}else{		
		glm::vec2 ratio = glm::vec2(ROOM_WIDTH/path["windowSize"][0].asFloat(), ROOM_DEPTH/path["windowSize"][1].asFloat());
		for(auto point : path["points"]) {
			// Reverse co-ordinates because player is facing down z axis
			float x = /*ratio.y * */point[0].asFloat();
			float z = /*ratio.x * */point[1].asFloat() / glm::length(ratio);
			points.push_back(glm::vec2(x, z));	
		}
	}

	// setup the artist
	artist = new MY_MakeupArtist(baseShader, points);
	childTransform->addChild(artist);//->scale(0.9);

	palette = new MY_Palette(bulletWorld, baseShader);
	childTransform->addChild(palette);
	palette->translateComponents(glm::vec3(0, 3, 2));

	

	// parse palettes
	{
		Json::Reader reader;
		Json::Value json;
		bool parsingSuccessful;
	
		parsingSuccessful = reader.parse(sweet::FileUtils::readFile("assets/palettes.json"), json);

		assert(parsingSuccessful);

		for(Json::Value::ArrayIndex i = 0; i < json["palettes"].size(); ++i){
			paletteDefs.push_back(new MY_Palette_Definition(json["palettes"][i].get("name", "NO_NAME").asString(), MY_ResourceManager::globalAssets->getTexture(json["palettes"][i].get("texture", "DEFAULT").asString())->texture));
		}
	}

	Sprite * sprite = new Sprite(MY_ResourceManager::globalAssets->getTexture("indicator")->texture, indicatorShader);

	auto sd = sweet::getWindowDimensions();
	uiLayer->resize(0, sd.x, 0, sd.y);

	VerticalLinearLayout * crosshairLayout = new VerticalLinearLayout(uiLayer->world);
	crosshairLayout->setRationalWidth(1.0f, uiLayer);
	crosshairLayout->setRationalHeight(1.0f, uiLayer);
	crosshairLayout->horizontalAlignment = kCENTER;
	crosshairLayout->verticalAlignment = kMIDDLE;

	NodeUI * crossHair = new NodeUI(uiLayer->world);
	crossHair->setWidth(15);
	crossHair->setHeight(15);
	crossHair->background->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("crosshair")->texture);
	crossHair->background->mesh->setScaleMode(GL_NEAREST);

	crosshairLayout->addChild(crossHair);

	crossHair->childTransform->addChild(sprite)->scale(100)->translate(7.5f, 7.5f, 0.f);

	uiLayer->addChild(crosshairLayout);

	
	// setup mirror
	mirrorCamera = new PerspectiveCamera();
	childTransform->addChild(mirrorCamera);
	cameras.push_back(mirrorCamera);
	mirrorCamera->firstParent()->translate(-0.5f, 3.25f, 4, false);

	mirrorFBO = new StandardFrameBuffer(true);
	mirrorTex = new FBOTexture(mirrorFBO, true, 0, false);
	mirrorTex->load();
	mirrorSurface = new MeshEntity(MY_ResourceManager::globalAssets->getMesh("salon-mirror")->meshes.at(0), mirrorShader);
	mirrorSurface->mesh->setScaleMode(GL_LINEAR);
	mirrorSurface->mesh->uvEdgeMode = GL_CLAMP_TO_EDGE;
	mirrorSurface->mesh->pushTexture2D(mirrorTex);
	childTransform->addChild(mirrorSurface);
	mirrorFBO->incrementReferenceCount();


	// memory management
	screenSurface->incrementReferenceCount();
	screenSurfaceShader->incrementReferenceCount();
	screenFBO->incrementReferenceCount();



	// load the tracks
	tracks = new Tracks();

	// start the experience
	getNextTrack();
	loadNextPalette();



	fade = new NodeUI(uiLayer->world);
	uiLayer->addChild(fade);
	fade->setRationalHeight(1.f, uiLayer);
	fade->setRationalWidth(1.f, uiLayer);
	fade->setBackgroundColour(0,0,0,1);

	Timeout * fadeIn = new Timeout(1.f, [this](sweet::Event * _event){
		fade->setVisible(false);
	});
	fadeIn->eventManager->addEventListener("progress", [this](sweet::Event * _event){
		float p = _event->getFloatData("progress");
		fade->setBackgroundColour(0,0,0,1.f-p);
	});
	fadeIn->start();
	childTransform->addChild(fadeIn, false);


	// recenter HMD
	ovr_RecenterPose(*sweet::hmd);

	startTime = glfwGetTime();
}