1 #include "pch.h"
2 #include "RenderConst.h"
3 #include "Def_Str.h"
4 #include "data/SceneXml.h"
5 #include "data/FluidsXml.h"
6 #include "data/CData.h"
7 #include "ShapeData.h"
8 #include "WaterRTT.h"
9 #include "CScene.h"
10 #ifdef SR_EDITOR
11 	#include "../../editor/CApp.h"
12 	#include "../../editor/settings.h"
13 	#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
14 #else
15 	#include "../CGame.h"
16 	#include "../../vdrift/game.h"
17 	//#include "../../vdrift/settings.h"
18 #endif
19 #include <BulletCollision/CollisionDispatch/btCollisionObject.h>
20 #include <BulletCollision/CollisionShapes/btBoxShape.h>
21 #include <OgreManualObject.h>
22 #include <OgreMeshManager.h>
23 #include <OgreMaterialManager.h>
24 #include <OgreEntity.h>
25 #include <OgreSceneManager.h>
26 #include <OgreSceneNode.h>
27 #include <OgreMesh.h>
28 #include <OgreTimer.h>
29 #include "../shiny/Main/Factory.hpp"
30 using namespace Ogre;
31 
32 
33 
34 ///  create Fluid areas  . . . . . . .
35 //----------------------------------------------------------------------------------------------------------------------
CreateFluids()36 void CScene::CreateFluids()
37 {
38 	vFlNd.clear();  vFlEnt.clear();  vFlSMesh.clear();
39 	#ifdef SR_EDITOR
40 	app->UpdFluidBox();
41 	#endif
42 	if (!mWaterRTT->mNdFluidsRoot)
43 		mWaterRTT->mNdFluidsRoot = app->mSceneMgr->getRootSceneNode()->createChildSceneNode("FluidsRootNode");
44 
45 	for (int i=0; i < sc->fluids.size(); ++i)
46 	{
47 		FluidBox& fb = sc->fluids[i];
48 		//  plane
49 		Plane p;  p.normal = Vector3::UNIT_Y;  p.d = 0;
50 		String smesh = "WaterMesh"+toStr(i);
51 		MeshPtr mesh = MeshManager::getSingleton().createPlane( smesh, rgDef,
52 			p, fb.size.x,fb.size.z, 6,6, true, 1, fb.tile.x*fb.size.x,fb.tile.y*fb.size.z, Vector3::UNIT_Z);
53 
54 		Entity* efl = app->mSceneMgr->createEntity("WaterPlane"+toStr(i), "WaterMesh"+toStr(i));
55 		unsigned short src,dest;
56 		if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src,dest))
57 			mesh->buildTangentVectors(VES_TANGENT, src,dest);
58 
59 		String sMtr = fb.id == -1 ? "" : data->fluids->fls[fb.id].material;  //"Water"+toStr(1+fb.type)
60 		MaterialPtr mtr = MaterialManager::getSingleton().getByName(sMtr);  //temp
61 
62 		efl->setMaterial(mtr);  efl->setCastShadows(false);
63 		efl->setRenderQueueGroup(RQG_Fluid);  efl->setVisibilityFlags(RV_Terrain);
64 
65 		SceneNode* nfl = mWaterRTT->mNdFluidsRoot->createChildSceneNode(
66 			fb.pos/*, Quaternion(Degree(fb.rot.x),Vector3::UNIT_Y)*/);
67 		nfl->attachObject(efl);
68 
69 		vFlSMesh.push_back(smesh);  vFlEnt.push_back(efl);  vFlNd.push_back(nfl);
70 
71 		#ifndef SR_EDITOR  // game
72 		CreateBltFluids();
73 		#endif
74 	}
75 }
76 
CreateBltFluids()77 void CScene::CreateBltFluids()
78 {
79 	for (int i=0; i < sc->fluids.size(); ++i)
80 	{
81 		FluidBox& fb = sc->fluids[i];
82 		const FluidParams& fp = sc->pFluidsXml->fls[fb.id];
83 
84 		///  add bullet trigger box   . . . . . . . . .
85 		btVector3 pc(fb.pos.x, -fb.pos.z, fb.pos.y -fb.size.y/2);  // center
86 		btTransform tr;  tr.setIdentity();  tr.setOrigin(pc);
87 		//tr.setRotation(btQuaternion(0, 0, fb.rot.x*PI_d/180.f));
88 
89 		btCollisionShape* bshp = 0;
90 		btScalar t = sc->td.fTerWorldSize*0.5f;  // not bigger than terrain
91 		bshp = new btBoxShape(btVector3(std::min(t, fb.size.x*0.5f), std::min(t, fb.size.z*0.5f), fb.size.y*0.5f));
92 
93 		//  solid surf
94 		size_t id = SU_Fluid;  if (fp.solid)  id += fp.surf;
95 		bshp->setUserPointer((void*)id);
96 
97 		btCollisionObject* bco = new btCollisionObject();
98 		bco->setActivationState(DISABLE_SIMULATION);
99 		bco->setCollisionShape(bshp);	bco->setWorldTransform(tr);
100 
101 		if (!fp.solid)  // fluid
102 			bco->setCollisionFlags(bco->getCollisionFlags() |
103 				btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_NO_CONTACT_RESPONSE/**/);
104 		else  // solid
105 		{	bco->setCollisionFlags(bco->getCollisionFlags() |
106 				btCollisionObject::CF_STATIC_OBJECT);
107 			bco->setFriction(0.6f);  bco->setRestitution(0.f);  //par?..
108 		}
109 
110 		bco->setUserPointer(new ShapeData(ST_Fluid, 0, &fb));  ///~~
111 		#ifndef SR_EDITOR
112 			app->pGame->collision.world->addCollisionObject(bco);
113 			app->pGame->collision.shapes.push_back(bshp);
114 			fb.cobj = bco;
115 		#else
116 			app->world->addCollisionObject(bco);
117 		#endif
118 	}
119 	#ifdef SR_EDITOR
120 	app->UpdObjPick();
121 	#endif
122 }
123 
DestroyFluids()124 void CScene::DestroyFluids()
125 {
126 	for (int i=0; i < vFlSMesh.size(); ++i)
127 	{
128 		vFlNd[i]->detachAllObjects();
129 		app->mSceneMgr->destroyEntity(vFlEnt[i]);
130 		app->mSceneMgr->destroySceneNode(vFlNd[i]);
131 		Ogre::MeshManager::getSingleton().remove(vFlSMesh[i]);
132 	}
133 	vFlNd.clear();  vFlEnt.clear();  vFlSMesh.clear();
134 }
135 
136 #ifdef SR_EDITOR
UpdFluidBox()137 void App::UpdFluidBox()
138 {
139 	int fls = scn->sc->fluids.size();
140 	bool bFluids = edMode == ED_Fluids && fls > 0 && !bMoveCam;
141 	if (fls > 0)
142 		iFlCur = std::max(0, std::min(iFlCur, fls-1));
143 
144 	if (!ndFluidBox)  return;
145 	ndFluidBox->setVisible(bFluids);
146 	if (!bFluids)  return;
147 
148 	FluidBox& fb = scn->sc->fluids[iFlCur];
149 	ndFluidBox->setPosition(fb.pos);
150 	ndFluidBox->setScale(fb.size);
151 }
152 
UpdMtrWaterDepth()153 void App::UpdMtrWaterDepth()
154 {
155 	float fl = edMode == ED_Fluids ? 0.f : 1.f;
156 	sh::Factory::getInstance().setSharedParameter("waterDepth", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(fl)));
157 }
158 #endif
159 
160 
161 //  Water rtt, setup and recreate
UpdateWaterRTT(Camera * cam)162 void CScene::UpdateWaterRTT(Camera* cam)
163 {
164 	mWaterRTT->setRTTSize(ciShadowSizesA[app->pSet->water_rttsize]);
165 	mWaterRTT->setReflect(app->pSet->water_reflect);
166 	mWaterRTT->setRefract(app->pSet->water_refract);
167 
168 	mWaterRTT->setViewerCamera(cam);
169 	mWaterRTT->mSceneMgr = app->mSceneMgr;
170 
171 	if (!sc->fluids.empty())  // first fluid's plane
172 		mWaterRTT->setPlane(Plane(Vector3::UNIT_Y, sc->fluids.front().pos.y));
173 	mWaterRTT->recreate();
174 	mWaterRTT->setActive(!sc->fluids.empty());
175 }
176