00001 #include <iostream>
00002 #include <sstream>
00003 #include <string>
00004 #include <fstream>
00005 #include <vector>
00006 #include <time.h>
00007 #include <stdlib.h>
00008 #include <math.h>
00009
00010 #include <btBulletDynamicsCommon.h>
00011 #include "Horde3D.h"
00012 #include "Horde3DUtils.h"
00013
00014 #include "World.h"
00015 #include "Physics.h"
00016 #include "Vec3.h"
00017 #include "Game.h"
00018 #include "Explosive.h"
00019
00025 World::World(Game* game, Physics* physics) {
00026 _debugMode = false;
00027 _waterAnimationTime = 0.0f;
00028 _game = game;
00029 _physics = physics;
00030 buildGraphicsWorld();
00031 buildPhysicsWorld();
00032 }
00033
00041 void World::buildGraphicsWorld() {
00042
00043 H3DRes envRes = h3dAddResource(H3DResTypes::SceneGraph, "models/world/world.scene.xml", 0 );
00044
00045
00046 H3DRes vulcanoRes = h3dAddResource(H3DResTypes::SceneGraph, "particles/vulcanoSmoke/vulcanoSmoke.scene.xml", 0);
00047 H3DRes houseRes = h3dAddResource(H3DResTypes::SceneGraph, "models/house/house.scene.xml", 0);
00048 H3DRes waterTowerRes = h3dAddResource(H3DResTypes::SceneGraph, "models/watertower/watertower.scene.xml", 0);
00049 _waterplaneRes = h3dAddResource(H3DResTypes::SceneGraph, "models/waterplane/watersurface.scene.xml", 0);
00050 H3DRes stopSignRes = h3dAddResource(H3DResTypes::SceneGraph, "models/signs/stop.scene.xml", 0);
00051 H3DRes treeRes = h3dAddResource(H3DResTypes::SceneGraph, "models/tree/tree.scene.xml", 0);
00052 H3DRes jeepRes = h3dAddResource(H3DResTypes::SceneGraph, "models/jeep/jeep.scene.xml", 0);
00053 H3DRes barrelRes = h3dAddResource(H3DResTypes::SceneGraph, "models/barrel/barrel.scene.xml", 0);
00054
00055 H3DRes barrel2Res = h3dAddResource(H3DResTypes::SceneGraph, "models/drum/drum.scene.xml", 0);
00056 _crateRes = h3dAddResource(H3DResTypes::SceneGraph, "models/crate/woodencrate.scene.xml", 0);
00057 H3DRes tireRes = h3dAddResource(H3DResTypes::SceneGraph, "models/tire/tire.scene.xml", 0);
00058
00059 H3DRes shipRes = h3dAddResource(H3DResTypes::SceneGraph, "models/ship/ship.scene.xml", 0);
00060
00061
00062 bool loaded = h3dutLoadResourcesFromDisk(::Values::CONTENT_DIR);
00063 if(! loaded) std::cout << "could not load one or more world ressources" << std::endl;
00064
00065 H3DNode model = h3dAddNodes(H3DRootNode, envRes);
00066
00067
00068 h3dSetNodeTransform(model, 0, -10, 0, 0, 0, 0, ::Values::WORLD_SCALE, ::Values::WORLD_SCALE, ::Values::WORLD_SCALE);
00069
00070
00071
00072 Game::addLight(H3DRootNode, "Light1", 200, 300, -170,
00073 -30, 110, 0,
00074 1900, 140, 4,
00075 1,1,1);
00076
00077
00078
00079
00080
00081
00082 Game::addLight(H3DRootNode, "Vulcano", -84.5, 34.5, -134,
00083 90, 0, 0,
00084 70, 120, 1,
00085 1, 0.3f, 0.5f);
00086
00087
00088 _vulcanoEmitter = h3dAddNodes(H3DRootNode, vulcanoRes);
00089 h3dSetNodeTransform(_vulcanoEmitter, -84.5, 34.5, -134,
00090 90, 0, 0,
00091 1, 1, 1);
00092
00093
00094
00095 H3DNode waterplane = h3dAddNodes(H3DRootNode, _waterplaneRes);
00096 h3dSetNodeTransform(waterplane, -50, -25.8f, 70, 0, 0, 0, 35, 0.001, 35);
00097
00098 H3DNode mesh = h3dGetNodeChild(waterplane, 0);
00099 std::cout << "found mesh " << mesh << std::endl;
00100 _waterplaneMeshMaterial = h3dGetNodeParamI(mesh, H3DMesh::MatResI);
00101 h3dSetMaterialUniform(_waterplaneMeshMaterial, "waterTime", 0.01f, 0.01f, 0.01f, 0.01f);
00102
00103 std::cout << "found material " << _waterplaneMeshMaterial << std::endl;
00104 int idx = h3dFindResElem(_waterplaneMeshMaterial, H3DMatRes::SamplerElem, H3DMatRes::SampNameStr, "albedoMap");
00105 std::cout << "found index " << idx << std::endl;
00106 H3DRes texRes = h3dGetResParamI(_waterplaneMeshMaterial, H3DMatRes::SamplerElem, idx, H3DMatRes::SampTexResI);
00107 std::cout << "found texres " << texRes << std::endl;
00108 h3dSetResParamI(_waterplaneMeshMaterial, H3DMatRes::SamplerElem, idx, H3DMatRes::SampTexResI, _game->getReflectionTexture());
00109 std::cout << "reflex res " << _game->getReflectionTexture() << std::endl;
00110
00111 int idx2 = h3dFindResElem(_waterplaneMeshMaterial, H3DMatRes::SamplerElem, H3DMatRes::SampNameStr, "ambientMap");
00112 std::cout << "found index2 " << idx2 << std::endl;
00113 H3DRes texRes2 = h3dGetResParamI(_waterplaneMeshMaterial, H3DMatRes::SamplerElem, idx2, H3DMatRes::SampTexResI);
00114 std::cout << "found texres2 " << texRes2 << std::endl;
00115 h3dSetResParamI(_waterplaneMeshMaterial, H3DMatRes::SamplerElem, idx2, H3DMatRes::SampTexResI, _game->getReflectionTexture());
00116 std::cout << "reflex res2 " << _game->getReflectionTexture() << std::endl;
00117
00118
00119
00120
00121 addModel(houseRes, Vec3(-110, -4.8f, 21), Vec3(0, 90, 0), 0.2);
00122 addModel(waterTowerRes, Vec3(-119, -9.8f, -14), Vec3(0, -90, 0), 10);
00123 addModel(stopSignRes, Vec3(-69, -8.1f, 13), Vec3(0, -90, 0), 0.25f);
00124 addModel(jeepRes, Vec3(-81, -8.9f, 16), Vec3(0, 71, 0), 3);
00125 addModel(_crateRes, Vec3(-73, -9, 12), Vec3(0, 71, 1), 1);
00126 addModel(barrel2Res, Vec3(-55, -9, 12), Vec3(0, 71, 1), 2);
00127 addModel(tireRes, Vec3(-57, -9.8f, 12), Vec3(0, 0, 90), 1);
00128 _ship = addModel(shipRes, Vec3(-85.7, -12.3f, 41.6f), Vec3(-13, -3, 3), 0.5);
00129
00130
00131 srand(time(NULL));
00132 for(int i = 0; i < 8; i++) {
00133 int rndx = rand() % 3;
00134 int rndz = (rand() % 65) + 10;
00135 addModel(treeRes, Vec3(-143 + rndx, -9.7f, 10 + rndz), Vec3(0, rndz + rndx, 0), 1.7f);
00136 }
00137
00138
00139 _models = std::vector<Explosive*>();
00140 Explosive* expl1 = new Explosive(_game, H3DRootNode, _physics, 0, barrelRes, Vec3(-75, -5.5f, -0.0f), Vec3(0, 0, 0), 0.33f);
00141 Explosive* expl2 = new Explosive(_game, H3DRootNode, _physics, 0, barrelRes, Vec3(-75, -7.5f, -0.5f), Vec3(0, 0, 0), 0.33f);
00142 Explosive* expl3 = new Explosive(_game, H3DRootNode, _physics, 0, barrel2Res, Vec3(-75, -8.0f, -1.0f), Vec3(0, 0, 0), 2.0f);
00143 _models.push_back(expl1);
00144 _models.push_back(expl2);
00145 _models.push_back(expl3);
00146 }
00147
00155 H3DNode World::addModel(H3DRes resource, Vec3 position, Vec3 rotation, float scale) {
00156 H3DNode model = h3dAddNodes(H3DRootNode, resource);
00157 h3dSetNodeTransform(model,
00158 position.x, position.y, position.z,
00159 rotation.x, rotation.y, rotation.z,
00160 scale, scale, scale);
00161 return model;
00162 }
00163
00168 bool World::testInboundXZ(const Vec3 position) {
00169 return false;
00170 }
00171
00176 void World::buildPhysicsWorld() {
00177
00178 std::string worldFilename("");
00179 worldFilename += Values::CONTENT_DIR;
00180 worldFilename += "/models/world/world.scene.obj";
00181
00182 std::ifstream file(worldFilename.c_str(), std::ifstream::in);
00183 if (!file) {
00184 std::cout << "Could not open file " << worldFilename.c_str() << std::endl;
00185 return;
00186 }
00187
00188
00189
00190 char type;
00191
00192 std::vector<Vec3> vertices;
00193 std::vector<int> indices;
00194
00195 int vertexCount = 0;
00196 int indexCount= 0;
00197
00198
00199
00200
00201 int vi = 0;
00202 int ii = 0;
00203
00204 while(! file.eof()) {
00205 file >> type;
00206
00207 if (type == '#') { std::string line; std::getline(file, line); }
00208 else if (type == 'm') { std::string line; std::getline(file, line); }
00209 else if (type == 'u') { std::string line; std::getline(file, line); }
00210 else if (type == 's') { std::string line; std::getline(file, line); }
00211
00212 else if (type == 'v') {
00213 float x, y, z;
00214 file >> x >> y >> z;
00215 vertices.push_back(Vec3(x, y, z) * ::Values::WORLD_SCALE);
00216 vi++;
00217 }
00218 else if (type == 'f') {
00219 int x, y, z;
00220 file >> x >> y >> z;
00221 indices.push_back(x);
00222 indices.push_back(y);
00223 indices.push_back(z);
00224 ii++;
00225 }
00226 }
00227
00228
00229 trimesh = new btTriangleMesh();
00230
00231 for (unsigned int i = 0; i < indices.size() / 3; i++) {
00232
00233 int index0 = indices[i * 3 + 0] - 1;
00234
00235
00236 int index1 = indices[i * 3 + 1] - 1;
00237 int index2 = indices[i * 3 + 2] - 1;
00238
00239 btVector3 vertex0(vertices[index0].x, vertices[index0].y, vertices[index0].z);
00240 btVector3 vertex1(vertices[index1].x, vertices[index1].y, vertices[index1].z);
00241 btVector3 vertex2(vertices[index2].x, vertices[index2].y, vertices[index2].z);
00242
00243 trimesh->addTriangle(vertex0, vertex1, vertex2);
00244 }
00245
00246 groundMotionState = new btDefaultMotionState(btTransform(
00247 btQuaternion(0,0,0,1),
00248 btVector3(0,-10,0))
00249 );
00250
00251
00252 btBvhTriangleMeshShape *shape = new btBvhTriangleMeshShape(trimesh, true);
00253
00254 btRigidBody::btRigidBodyConstructionInfo groundBodyCI(0, groundMotionState, shape, btVector3(0,0,0));
00255 body = new btRigidBody(groundBodyCI);
00256 _physics->addNonShootable(body);
00257
00258
00259
00260 addPhysicsBox(Vec3(233, 30, 2), Vec3(0,-8, 135), 0);
00261 addPhysicsBox(Vec3(233, 30, 2), Vec3(0,-8,-150), 0);
00262 addPhysicsBox(Vec3(2, 30, 250), Vec3(-120,-8,0), 0);
00263 addPhysicsBox(Vec3(2, 30, 250), Vec3(170,-8,0), 0);
00264
00265 addPhysicsBox(Vec3(2, 2, 5), Vec3(-52.9f,-8, 11), 0);
00266
00267 addPhysicsBox(Vec3(4, 12, 5), Vec3(170,-13, 80), 0);
00268 addPhysicsBox(Vec3(0.2f, 5, 0.2f), Vec3(49.9f,-7.4f,12.9f), 0);
00269 addPhysicsBox(Vec3(2, 12, 5), Vec3(170,-8,0), 0);
00270
00271
00272 addPhysicsBox(Vec3(0.3f, 0.3f, 2.3f), Vec3(-105.5f, -9.5f, 27.3f), 0);
00273 addPhysicsBox(Vec3(0.3f, 0.3f, 2.3f), Vec3(-106.0f, -9.0f, 27.3f), 0);
00274 addPhysicsBox(Vec3(0.3f, 0.3f, 2.3f), Vec3(-106.5f, -8.5f, 27.3f), 0);
00275 addPhysicsBox(Vec3(10.f, 0.3f, 5), Vec3(-117, -8.5f, 23.0f), 0);
00276
00277
00278
00279
00280
00281 }
00282
00288 void World::addPhysicsBox(const Vec3 halfsize, const Vec3 position, const float rotationY) {
00289 btCollisionShape* shape = new btBoxShape(btVector3(halfsize.x, halfsize.y, halfsize.z));
00290 btMotionState* motionState = new btDefaultMotionState(btTransform(
00291 btQuaternion(0,0,0,1),
00292 btVector3(position.x, position.y, position.z)));
00293 const float ZERO_MASS = 0.0f;
00294 btRigidBody* wall = new btRigidBody(ZERO_MASS, motionState, shape);
00295 wall->setActivationState(WANTS_DEACTIVATION);
00296 if(_debugMode) {
00297 H3DNode theNode = h3dAddNodes(H3DRootNode, _crateRes);
00298 h3dSetNodeTransform(theNode, position.x, position.y, position.z,
00299 0,0, rotationY, 2 * halfsize.x, 2 * halfsize.y, 2 * halfsize.z);
00300 }
00301
00302 _physics->addNonShootable(wall);
00303 }
00304
00309 void World::update(const float timeStep) {
00310 for(unsigned int i = 0; i < _models.size(); i++) {
00311 Explosive* exp = _models[i];
00312 exp->update(timeStep);
00313 }
00314
00315 Game::advanceEmitter(_vulcanoEmitter, timeStep);
00316
00317
00318 const float slownessFactor = 8.0f;
00319 _waterAnimationTime += timeStep / slownessFactor;
00320 float animationTime = tan(_waterAnimationTime);
00321
00322
00323 float notUsed = -1;
00324 h3dSetMaterialUniform(_waterplaneMeshMaterial, "waterTime", animationTime, notUsed, notUsed, notUsed);
00325
00326
00327 float ntx, nty, ntz;
00328 float nrx, nry, nrz;
00329 float nsx, nsy, nsz;
00330 h3dGetNodeTransform(_ship, &ntx, &nty, &ntz, &nrx, &nry, &nrz, &nsx, &nsy, &nsz);
00331 h3dSetNodeTransform(_ship, ntx, nty, ntz, animationTime * slownessFactor, nry, nrz, nsx, nsy, nsz);
00332 }
00333
00334 World::~World() {
00335
00336 for(unsigned int i = 0; i < _models.size(); i++) {
00337 delete _models[i];
00338 }
00339
00340
00341
00342
00343
00344
00345
00346 }