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