Add terrain in Scene3DTest.

This commit is contained in:
Vincent Yang 2015-05-08 11:46:27 +08:00
parent 6f50708beb
commit 966f3b6a3f
1 changed files with 145 additions and 42 deletions

View File

@ -1,16 +1,23 @@
#include "Scene3DTest.h"
#include "../testResource.h"
#include "TerrainTest.h"
USING_NS_CC;
////////////////////////////////////////////////////////////////////////////////
// Implements Scene3DTestScene
static Vec3 camera_offset(0, 45, 60);
class Scene3DTestScene : public TestCase
{
public:
CREATE_FUNC(Scene3DTestScene);
void onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
void onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
void onTouchesEnd(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
private:
Scene3DTestScene();
virtual ~Scene3DTestScene();
@ -20,20 +27,41 @@ private:
void createUI();
Node* createDialog();
std::vector<Camera *> _gameCameras;
Terrain *_terrain;
Player *_player;
static const int DLG_COUNT = 3;
std::vector<Node*> _dlgs;
};
#define GAME_SCENE_MASK CameraFlag::DEFAULT
#define GAME_UI_MASK CameraFlag::USER1
#define GAME_ACTOR_MASK CameraFlag::USER2
#define GAME_ZOOM_MASK CameraFlag::USER3
#define SCENE_CAMERA_DEPTH 0
#define UI_CAMERA_DEPTH 1
#define ACTOR_CAMERA_DEPTH 2
#define ZOOM_CAMERA_DEPTH 3
enum LAYER_DEPTH {
LAYER_DEPTH_GAME = 0,
LAYER_DEPTH_UI,
LAYER_DEPTH_ACTOR,
LAYER_DEPTH_ZOOM,
LAYER_DEPTH_COUNT,
};
static CameraFlag s_CF[LAYER_DEPTH_COUNT] = {
CameraFlag::DEFAULT,
CameraFlag::USER1,
CameraFlag::USER2,
CameraFlag::USER3,
};
static unsigned short s_CM[LAYER_DEPTH_COUNT] = {
(unsigned short)s_CF[0],
(unsigned short)s_CF[1],
(unsigned short)s_CF[2],
(unsigned short)s_CF[3],
};
Scene3DTestScene::Scene3DTestScene()
: _terrain(nullptr)
, _player(nullptr)
{
}
@ -54,6 +82,38 @@ bool Scene3DTestScene::init()
Director::getInstance()->setDisplayStats(false);
// prepare for camera creation, we need create three custom cameras
Size visibleSize = Director::getInstance()->getVisibleSize();
_gameCameras.resize(LAYER_DEPTH_COUNT);
// first, create a camera to look the 3d game scene
Camera *ca = Camera::createPerspective(60,visibleSize.width/visibleSize.height,0.1,200);
ca->setCameraFlag(s_CF[LAYER_DEPTH_GAME]);
ca->setDepth(LAYER_DEPTH_GAME);
_gameCameras[LAYER_DEPTH_GAME] = ca;
this->addChild(ca);
// second, use the default camera to look 2d base ui layer
ca =this->getDefaultCamera();
ca->setCameraFlag(s_CF[LAYER_DEPTH_UI]);
ca->setDepth(LAYER_DEPTH_UI);
_gameCameras[LAYER_DEPTH_UI] = ca;
// third, create a camera to look the 3d model in dialogs
ca = Camera::create();
ca->setCameraFlag(s_CF[LAYER_DEPTH_ACTOR]);
ca->setDepth(LAYER_DEPTH_ACTOR);
_gameCameras[LAYER_DEPTH_ACTOR] = ca;
this->addChild(ca);
// forth, create a camera to kook the ui element over on the 3d models
ca = Camera::create();
ca->setCameraFlag(s_CF[LAYER_DEPTH_ZOOM]);
ca->setDepth(LAYER_DEPTH_ZOOM);
_gameCameras[LAYER_DEPTH_ZOOM] = ca;
this->addChild(ca);
// create all object in game
create3DWorld();
createUI();
Size step = VisibleRect::getVisibleRect().size;
@ -70,7 +130,14 @@ bool Scene3DTestScene::init()
pos.x += step.width;
pos.y += step.height;
}
createDialog();
// add touch callback
// auto listener = EventListenerTouchAllAtOnce::create();
// listener->onTouchesBegan = CC_CALLBACK_2(Scene3DTestScene::onTouchesBegan, this);
// listener->onTouchesMoved = CC_CALLBACK_2(Scene3DTestScene::onTouchesMoved, this);
// listener->onTouchesEnded = CC_CALLBACK_2(Scene3DTestScene::onTouchesEnd, this);
// _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
ret = true;
} while (0);
@ -79,25 +146,64 @@ bool Scene3DTestScene::init()
void Scene3DTestScene::create3DWorld()
{
std::string filename = "Sprite3DTest/girl.c3b";
auto girl = Sprite3D::create(filename);
girl->setPosition(240, 0);
this->addChild(girl);
// Size visibleSize = Director::getInstance()->getVisibleSize();
auto camera = _gameCameras[LAYER_DEPTH_GAME];
// first, create terrain
Terrain::DetailMap r("TerrainTest/dirt.jpg");
Terrain::DetailMap g("TerrainTest/Grass2.jpg",10);
Terrain::DetailMap b("TerrainTest/road.jpg");
Terrain::DetailMap a("TerrainTest/GreenSkin.jpg",20);
Terrain::TerrainData data("TerrainTest/heightmap16.jpg",
"TerrainTest/alphamap.png",
r,g,b,a,Size(32,32),40.0f,2);
_terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
_terrain->setMaxDetailMapAmount(4);
_terrain->setCameraMask(s_CM[LAYER_DEPTH_GAME]);
_terrain->setDrawWire(false);
_terrain->setSkirtHeightRatio(3);
_terrain->setLODDistance(64,128,192);
this->addChild(_terrain);
// second, create actor
_player = Player::create("Sprite3DTest/girl.c3b",camera,_terrain);
_player->setCameraMask(s_CM[LAYER_DEPTH_GAME]);
_player->setScale(0.08);
_player->setPositionY(_terrain->getHeight(_player->getPositionX(),_player->getPositionZ()));
auto animation = Animation3D::create("Sprite3DTest/girl.c3b","Take 001");
if (animation)
{
auto animate = Animate3D::create(animation);
_player->runAction(RepeatForever::create(animate));
}
addChild(_player);
// third, set camera position
camera->setPosition3D(_player->getPosition3D()+camera_offset);
camera->setRotation3D(Vec3(-45,0,0));
}
void Scene3DTestScene::createUI()
{
auto uiCamera = Camera::create();
// uiCamera->setPositionX(uiCamera->getPositionX() + 50);
uiCamera->setCameraFlag(GAME_UI_MASK);
uiCamera->setDepth(UI_CAMERA_DEPTH);
this->addChild(uiCamera);
auto showDlgItem = MenuItemImage::create(s_pathClose, s_pathClose, [this](Ref* sender){
auto showLeftDlgItem = MenuItemImage::create(s_pathClose, s_pathClose, [this](Ref* sender){
this->_dlgs[0]->setVisible(!this->_dlgs[0]->isVisible());
});
showDlgItem->setPosition(VisibleRect::right().x - 30, VisibleRect::top().y - 30);
showLeftDlgItem->setPosition(VisibleRect::left().x + 30, VisibleRect::top().y - 30);
auto showMidDlgItem = MenuItemImage::create(s_pathClose, s_pathClose, [this](Ref* sender){
this->_dlgs[1]->setVisible(!this->_dlgs[1]->isVisible());
});
showMidDlgItem->setPosition(VisibleRect::top().x, VisibleRect::top().y - 30);
auto showRightDlgItem = MenuItemImage::create(s_pathClose, s_pathClose, [this](Ref* sender){
this->_dlgs[2]->setVisible(!this->_dlgs[2]->isVisible());
});
showRightDlgItem->setPosition(VisibleRect::right().x - 30, VisibleRect::top().y - 30);
auto uiCamera = _gameCameras[LAYER_DEPTH_UI];
auto moveCameraLeft = MenuItemImage::create(s_pathClose, s_pathClose, [uiCamera](Ref* sender){
uiCamera->setPositionX(uiCamera->getPositionX() - 10);
});
@ -108,9 +214,14 @@ void Scene3DTestScene::createUI()
});
moveCameraRight->setPosition(VisibleRect::right().x - 30, VisibleRect::right().y);
auto menu = Menu::create(showDlgItem, moveCameraLeft, moveCameraRight, nullptr);
auto menu = Menu::create(showLeftDlgItem,
showMidDlgItem,
showRightDlgItem,
moveCameraLeft,
moveCameraRight,
nullptr);
menu->setPosition(Vec2::ZERO);
menu->setCameraMask((unsigned short)GAME_UI_MASK, true);
menu->setCameraMask(s_CM[LAYER_DEPTH_UI], true);
this->addChild(menu);
}
@ -121,12 +232,14 @@ Node* Scene3DTestScene::createDialog()
int layerW = 240;
int layerH = 160;
int margin = 10;
auto layer = LayerColor::create(Color4B(166, 166, 166, 255), layerW, layerH);
//layer->setPosition(120, 80);
static char clr = 0x3f;
auto layer = LayerColor::create(Color4B(clr, clr, clr, 255), layerW, layerH);
clr = clr << 1;
layer->setVisible(false);
// add 2d ui element on dialog:
// actor background
auto actorBg = LayerColor::create(Color4B(0, 0, 0, 255), layerW / 2 - 2 * margin, layerH - 2 * margin - 16);
auto actorBg = LayerColor::create(Color4B(0, 0, 128, 255), layerW / 2 - 2 * margin, layerH - 2 * margin - 16);
actorBg->setPosition(margin, margin);
layer->addChild(actorBg);
@ -136,23 +249,18 @@ Node* Scene3DTestScene::createDialog()
layer->addChild(title);
// add layer to scene and set camera mask
layer->setCameraMask((unsigned short)GAME_UI_MASK);
layer->setCameraMask(s_CM[LAYER_DEPTH_UI]);
this->addChild(layer);
// add actor, which on dialog layer, and specify a camera for it
// add actor, which on dialog layer
std::string filename = "Sprite3DTest/girl.c3b";
auto girl = Sprite3D::create(filename);
girl->setScale(0.5);
girl->setPosition(100, -20);
girl->setCameraMask((unsigned short)GAME_ACTOR_MASK);
girl->setPosition(layerW / 4, margin * 3);
girl->setCameraMask(s_CM[LAYER_DEPTH_ACTOR]);
layer->addChild(girl);
auto actorCamera = Camera::create();
actorCamera->setCameraFlag(GAME_ACTOR_MASK);
actorCamera->setDepth(ACTOR_CAMERA_DEPTH);
this->addChild(actorCamera);
// add zoom in/out button, which is 2d ui element and over 3d actor, and specify a camera for it
// add zoom in/out button, which is 2d ui element and over 3d actor
auto zoomIn = MenuItemImage::create(s_pathClose, s_pathClose, [girl](Ref* sender){
girl->setScale(girl->getScale() * 2);
});
@ -165,14 +273,9 @@ Node* Scene3DTestScene::createDialog()
auto menu = Menu::create(zoomIn, zoomOut, nullptr);
menu->setPosition(Vec2::ZERO);
menu->setCameraMask((unsigned short)GAME_ZOOM_MASK, true);
menu->setCameraMask(s_CM[LAYER_DEPTH_ZOOM]);
layer->addChild(menu);
auto zoomBtnCamera = Camera::create();
zoomBtnCamera->setCameraFlag(GAME_ZOOM_MASK);
zoomBtnCamera->setDepth(ZOOM_CAMERA_DEPTH);
this->addChild(zoomBtnCamera);
return layer;
}