| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- #include "TerrainSample.h"
- #include "SamplesGame.h"
- #if defined(ADD_SAMPLE)
- ADD_SAMPLE("Scene", "Terrain", TerrainSample, 4);
- #endif
- struct TerrainHitFilter : public PhysicsController::HitFilter
- {
- TerrainHitFilter(Terrain* terrain)
- {
- terrainObject = terrain->getNode()->getCollisionObject();
- }
- bool filter(PhysicsCollisionObject* object)
- {
- // Filter out all objects but the terrain
- return (object != terrainObject);
- }
- PhysicsCollisionObject* terrainObject;
- };
- TerrainSample::TerrainSample()
- : _font(NULL), _scene(NULL), _terrain(NULL), _sky(NULL), _form(NULL), _formVisible(true),
- _wireframe(false), _debugPhysics(false), _snapToGround(true), _vsync(true),
- _mode(MODE_LOOK), _sphere(NULL), _box(NULL)
- {
- }
- TerrainSample::~TerrainSample()
- {
- SAFE_RELEASE(_box);
- SAFE_RELEASE(_sphere);
- SAFE_RELEASE(_form);
- SAFE_RELEASE(_font);
- SAFE_RELEASE(_scene);
- }
- void TerrainSample::initialize()
- {
- // Load scene
- _scene = Scene::load("res/common/terrain/sample.scene");
- _terrain = _scene->findNode("terrain")->getTerrain();
- _sky = _scene->findNode("sky");
- // Load shapes
- Bundle* bundle;
- bundle = Bundle::create("res/common/sphere.gpb");
- _sphere = bundle->loadNode("sphere");
- SAFE_RELEASE(bundle);
- bundle = Bundle::create("res/common/box.gpb");
- _box = bundle->loadNode("box");
- SAFE_RELEASE(bundle);
- // Load font
- _font = Font::create("res/common/arial.gpb");
- // Setup form
- _form = Form::create("res/common/terrain/terrain.form");
- _form->getControl("plusButton")->addListener(this, Control::Listener::CLICK);
- _form->getControl("minusButton")->addListener(this, Control::Listener::CLICK);
- _form->getControl("wireframe")->addListener(this, Control::Listener::VALUE_CHANGED);
- _form->getControl("patches")->addListener(this, Control::Listener::VALUE_CHANGED);
- _form->getControl("physics")->addListener(this, Control::Listener::VALUE_CHANGED);
- _form->getControl("lod")->addListener(this, Control::Listener::VALUE_CHANGED);
- _form->getControl("culling")->addListener(this, Control::Listener::VALUE_CHANGED);
- _form->getControl("snapToGround")->addListener(this, Control::Listener::VALUE_CHANGED);
- _form->getControl("dropSphere")->addListener(this, Control::Listener::CLICK);
- _form->getControl("dropBox")->addListener(this, Control::Listener::CLICK);
- _form->getControl("clearAll")->addListener(this, Control::Listener::CLICK);
- Control* main = _form->getControl("main");
- _formSize.set(main->getWidth(), main->getHeight());
- // Use script camera for navigation
- enableScriptCamera(true);
- setScriptCameraSpeed(20, 80);
- }
- void TerrainSample::finalize()
- {
- SAFE_RELEASE(_font);
- SAFE_RELEASE(_scene);
- SAFE_RELEASE(_form);
- SAFE_RELEASE(_sphere);
- SAFE_RELEASE(_box);
- }
- void TerrainSample::update(float elapsedTime)
- {
- Node* camera = _scene->getActiveCamera()->getNode();
- if (_snapToGround)
- {
- // Get current camera location in world coords
- Vector3 pos = camera->getTranslationWorld();
- // Query the height of our terrain at this location
- float height = _terrain->getHeight(pos.x, pos.z);
- // Snap our camera to the ground
- camera->setTranslationY(height + 10);
- }
- // Keep the sky centered around the viewer
- _sky->setTranslationX(camera->getTranslationX());
- _sky->setTranslationZ(camera->getTranslationZ());
- // Prune dropped physics shapes that fall off the terrain
- for (std::list<Node*>::iterator itr = _shapes.begin(); itr != _shapes.end(); )
- {
- Node* shape = *itr;
- if (shape->getTranslation().y < 0)
- {
- _scene->removeNode(shape);
- std::list<Node*>::iterator oldItr = itr;
- ++itr;
- _shapes.erase(oldItr);
- }
- else
- {
- ++itr;
- }
- }
- }
- void TerrainSample::render(float elapsedTime)
- {
- clear(Game::CLEAR_COLOR_DEPTH, 0, 0, 0, 1, 1, 0);
- // Draw scene
- _scene->visit(this, &TerrainSample::drawScene);
- // Debug draw
- if (_debugPhysics)
- Game::getInstance()->getPhysicsController()->drawDebug(_scene->getActiveCamera()->getViewProjectionMatrix());
- // Draw form
- _form->draw();
- // Draw text
- char buffer[1024];
- sprintf(buffer, "FPS: %d", getFrameRate());
- _font->start();
- _font->drawText(buffer, 65, 18, Vector4::one(), 30);
- if (_formVisible)
- {
- // Draw stats
- sprintf(buffer,
- "Total Patches: %d\n" \
- "Visible Patches: %d\n" \
- "Total Triangles: %d\n" \
- "Visible Triangles: %d\n",
- _terrain->getPatchCount(),
- _terrain->getVisiblePatchCount(),
- _terrain->getTriangleCount(),
- _terrain->getVisibleTriangleCount());
- _font->drawText(buffer, 25, 300, Vector4::one(), 20);
- }
- _font->finish();
- }
- bool TerrainSample::drawScene(Node* node)
- {
- if (node->getModel())
- {
- node->getModel()->draw();
- }
- else if (node->getTerrain())
- {
- node->getTerrain()->draw(_wireframe);
- }
- return true;
- }
- void TerrainSample::keyEvent(Keyboard::KeyEvent evt, int key)
- {
- // Process keyboard shortcuts for options
- if (evt == Keyboard::KEY_PRESS)
- {
- switch (key)
- {
- case Keyboard::KEY_ONE:
- {
- CheckBox* cb = static_cast<CheckBox*>(_form->getControl("wireframe"));
- cb->setChecked(!cb->isChecked());
- }
- break;
- case Keyboard::KEY_TWO:
- {
- CheckBox* cb = static_cast<CheckBox*>(_form->getControl("patches"));
- cb->setChecked(!cb->isChecked());
- }
- break;
- case Keyboard::KEY_THREE:
- {
- CheckBox* cb = static_cast<CheckBox*>(_form->getControl("physics"));
- cb->setChecked(!cb->isChecked());
- }
- break;
- case Keyboard::KEY_FOUR:
- {
- CheckBox* cb = static_cast<CheckBox*>(_form->getControl("lod"));
- cb->setChecked(!cb->isChecked());
- }
- break;
- case Keyboard::KEY_FIVE:
- {
- CheckBox* cb = static_cast<CheckBox*>(_form->getControl("culling"));
- cb->setChecked(!cb->isChecked());
- }
- break;
- case Keyboard::KEY_SIX:
- {
- CheckBox* cb = static_cast<CheckBox*>(_form->getControl("snapToGround"));
- cb->setChecked(!cb->isChecked());
- }
- break;
- }
- }
- }
- void TerrainSample::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
- {
- if (evt == Touch::TOUCH_PRESS)
- {
- // If the FPS region is touched, toggle vsync (if platform supports it)
- if (x >= 65 && x < 300 && y >= 18 && y <= 48)
- {
- _vsync = !_vsync;
- setVsync(_vsync);
- }
- else if (_mode != MODE_LOOK)
- {
- // Ray sample
- Ray pickRay;
- _scene->getActiveCamera()->pickRay(Rectangle (0, 0, getWidth(), getHeight()), x, y, &pickRay);
- PhysicsController::HitResult hitResult;
- TerrainHitFilter hitFilter(_terrain);
- if (Game::getInstance()->getPhysicsController()->rayTest(pickRay, 1000000, &hitResult, &hitFilter) && hitResult.object == _terrain->getNode()->getCollisionObject())
- {
- Node* clone = NULL;
- PhysicsCollisionShape::Definition rbShape;
- const char* material = NULL;
- switch (_mode)
- {
- case MODE_DROP_SPHERE:
- {
- clone = _sphere->clone();
- rbShape = PhysicsCollisionShape::sphere();
- material = "res/common/terrain/shapes.material#sphere";
- }
- break;
- case MODE_DROP_BOX:
- {
- clone = _box->clone();
- rbShape = PhysicsCollisionShape::box();
- material = "res/common/terrain/shapes.material#box";
- }
- break;
- }
- if (clone)
- {
- clone->setScale(10,10,10);
- clone->setTranslation(hitResult.point.x, hitResult.point.y + 50, hitResult.point.z);
- PhysicsRigidBody::Parameters rbParams(1);
- clone->setCollisionObject(PhysicsCollisionObject::RIGID_BODY, rbShape, &rbParams);
- _scene->addNode(clone);
- clone->getModel()->setMaterial(material);
- clone->release();
- _shapes.push_back(clone);
- _mode = MODE_LOOK;
- setMessage(NULL);
- }
- }
- }
- }
- }
- bool TerrainSample::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
- {
- return false;
- }
- void TerrainSample::controlEvent(Control* control, EventType evt)
- {
- if (strcmp(control->getId(), "plusButton") == 0)
- {
- control->setVisible(false);
- _form->getControl("minusButton")->setVisible(true);
- _form->getControl("settings")->setVisible(true);
- _form->getControl("physicsSettings")->setVisible(true);
- _form->getControl("main")->setSize(_formSize.x, _formSize.y);
- _formVisible = true;
- }
- else if (strcmp(control->getId(), "minusButton") == 0)
- {
- control->setVisible(false);
- _form->getControl("plusButton")->setVisible(true);
- _form->getControl("settings")->setVisible(false);
- _form->getControl("physicsSettings")->setVisible(false);
- _form->getControl("main")->setSize(50, 50);
- _formVisible = false;
- }
- else if (strcmp(control->getId(), "wireframe") == 0)
- {
- _wireframe = static_cast<CheckBox*>(control)->isChecked();
- }
- else if (strcmp(control->getId(), "patches") == 0)
- {
- _terrain->setFlag(Terrain::DEBUG_PATCHES, static_cast<CheckBox*>(control)->isChecked());
- }
- else if (strcmp(control->getId(), "physics") == 0)
- {
- _debugPhysics = static_cast<CheckBox*>(control)->isChecked();
- }
- else if (strcmp(control->getId(), "lod") == 0)
- {
- _terrain->setFlag(Terrain::LEVEL_OF_DETAIL, static_cast<CheckBox*>(control)->isChecked());
- }
- else if (strcmp(control->getId(), "culling") == 0)
- {
- _terrain->setFlag(Terrain::FRUSTUM_CULLING, static_cast<CheckBox*>(control)->isChecked());
- }
- else if (strcmp(control->getId(), "snapToGround") == 0)
- {
- _snapToGround = static_cast<CheckBox*>(control)->isChecked();
- if (_snapToGround)
- setScriptCameraSpeed(20, 80);
- else
- setScriptCameraSpeed(200, 800);
- }
- else if (strcmp(control->getId(), "dropSphere") == 0)
- {
- if (_mode == MODE_DROP_SPHERE)
- {
- _mode = MODE_LOOK;
- setMessage(NULL);
- }
- else
- {
- _mode = MODE_DROP_SPHERE;
- setMessage("Click on the terrain to drop a sphere.");
- }
- }
- else if (strcmp(control->getId(), "dropBox") == 0)
- {
- if (_mode == MODE_DROP_BOX)
- {
- _mode = MODE_LOOK;
- setMessage(NULL);
- }
- else
- {
- _mode = MODE_DROP_BOX;
- setMessage("Click on the terrain to drop a box.");
- }
- }
- else if (strcmp(control->getId(), "clearAll") == 0)
- {
- for (std::list<Node*>::iterator itr = _shapes.begin(); itr != _shapes.end(); ++itr)
- _scene->removeNode(*itr);
- _shapes.clear();
- }
- }
- void TerrainSample::setMessage(const char* message)
- {
- Label* label = static_cast<Label*>(_form->getControl("message"));
- label->setText(message ? message : "");
- _form->getControl("messageBox")->setVisible(message ? true : false);
- }
|