PuzzleSDK
Scene3DTest.cpp
浏览该文件的文档.
1/****************************************************************************
2 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
3
4 http://www.cocos2d-x.org
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 ****************************************************************************/
24
25#include "Scene3DTest.h"
26
27#include "ui/CocosGUI.h"
28#include "renderer/CCRenderState.h"
29#include <spine/spine-cocos2dx.h>
30
31#include "../testResource.h"
32#include "../TerrainTest/TerrainTest.h"
33
35using namespace spine;
36
37class SkeletonAnimationCullingFix : public SkeletonAnimation
38{
39public:
41 : SkeletonAnimation()
42 {}
43
44 virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override
45 {
46 glDisable(GL_CULL_FACE);
47 SkeletonAnimation::draw(renderer, transform, transformFlags);
48 RenderState::StateBlock::invalidate(cocos2d::RenderState::StateBlock::RS_ALL_ONES);
49 }
50
51 static SkeletonAnimationCullingFix* createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1)
52 {
54 spAtlas* atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
55 node->initWithJsonFile(skeletonDataFile, atlas, scale);
56 node->autorelease();
57 return node;
58 }
59};
60
62// Declare Scene3DTestScene
63
76{
77public:
79
80 bool onTouchBegan(Touch* touch, Event* event) { return true; }
81 void onTouchEnd(Touch*, Event*);
82
83private:
85 virtual ~Scene3DTestScene();
86 bool init() override;
87
88 void createWorld3D();
89 void createUI();
90 void createPlayerDlg();
91 void createDetailDlg();
92 void createDescDlg();
93
94 // init in init()
95 std::vector<Camera *> _gameCameras;
97 Node* _dlgScene;
98 Node* _osdScene;
99
100 // init in createWorld3D()
101 TextureCube* _textureCube;
102 Skybox* _skyBox;
103 cocos2d::Terrain* _terrain;
105 Node* _monsters[2];
106
107 // init in createUI()
111 Node* _ui;
112
113 // init in createPlayerDlg()
115 // init in createDetailDlg()
117 // init in createDescDlg()
118 Node* _descDlg;
120 {
121 HAIR = 0,
129 };
130
131 std::vector<std::string> _skins[(int)SkinType::MAX_TYPE]; //all skins
132 int _curSkin[(int)SkinType::MAX_TYPE]; //current skin index
133 cocos2d::Sprite3D* _reskinGirl;
134
135 // for capture screen
136 static const int SNAPSHOT_TAG = 119;
137 std::string _snapshotFile;
138};
139
147};
148
156};
157
170};
171
172/*
173 Defined s_CF and s_CM to avoid force conversion when call Camera::setCameraFlag
174 and Node::setCameraMask.
175
176 Usage:
177 - Camera::setCameraFlag(s_CF[<SCENE_LAYER_INDEX>]);
178 - Node::setCameraMask(s_CM[<SCENE_LAYER_INDEX>]);
179
180 Note:
181 For LAYER_DEFAULT, we use CameraFlag::DEFAULT, thus we don't need to set
182 camera flag/mask for this layer, for other layers we must to set camera
183 flag/mask to distinguish between each other.
184 */
185static CameraFlag s_CF[LAYER_COUNT] =
186{
187 CameraFlag::USER1, // LAYER_BACKGROUND
188 CameraFlag::DEFAULT, // LAYER_DEFAULT
189 CameraFlag::USER3, // LAYER_MIDDLE
190 CameraFlag::USER4, // LAYER_TOP
191};
192
193static unsigned short s_CM[LAYER_COUNT] =
194{
195 (unsigned short)s_CF[0],
196 (unsigned short)s_CF[1],
197 (unsigned short)s_CF[2],
198 (unsigned short)s_CF[3],
199};
200
201static const char * s_CameraNames[CAMERA_COUNT] =
202{
203 "World 3D Skybox",
204 "World 3D Scene",
205 "UI 2D",
206 "Dialog 2D Base",
207 "Dialog 3D Model",
208 "Dialog 2D Above",
209 "OSD 2D Base",
210 "OSD 3D Model",
211 "OSD 2D Above"
212};
213
216 Vec3(0, 0, 0), // center : UI scene
217 Vec3(0, 10000, 0), // top : World sub scene
218 Vec3(10000, 0, 0), // right : Dialog sub scene
219 Vec3(0, -10000, 0), // bottom : OSD sub scene
220};
221
223// Implements Scene3DTestScene
224
226: _worldScene(nullptr)
227, _dlgScene(nullptr)
228, _osdScene(nullptr)
229, _textureCube(nullptr)
230, _skyBox(nullptr)
231, _terrain(nullptr)
232, _player(nullptr)
233, _playerItem(nullptr)
234, _detailItem(nullptr)
235, _descItem(nullptr)
236, _ui(nullptr)
237, _playerDlg(nullptr)
238, _detailDlg(nullptr)
239, _descDlg(nullptr)
240{
241 _monsters[0] = _monsters[1] = nullptr;
242}
243
245{
246}
247
249{
250 bool ret = false;
251 do
252 {
253 CC_BREAK_IF(false == TestCase::init());
254
255 // prepare for camera creation, we need several custom cameras
257 auto visibleSize = Director::getInstance()->getVisibleSize();
258 Camera *ca = nullptr; // temp variable
259
261 // create world 3D scene, this scene has two camera
262 _worldScene = Node::create();
263 // create a camera to look the skybox
265 Camera::createPerspective(60,
266 visibleSize.width / visibleSize.height,
267 10,
268 1000);
269 ca->setDepth(CAMERA_WORLD_3D_SKYBOX);
271 ca->setCameraFlag(s_CF[LAYER_BACKGROUND]);
272 ca->setPosition3D(Vec3(0.f, 0.f, 50.f));
273 _worldScene->addChild(ca);
274 // create a camera to look the 3D models in world 3D scene
276 Camera::createPerspective(60,
277 visibleSize.width/visibleSize.height,
278 0.1f,
279 200);
280 ca->setDepth(CAMERA_WORLD_3D_SCENE);
282 _worldScene->addChild(ca);
283 // create 3D objects and add to world scene
285 _worldScene->addChild(_skyBox);
286 _worldScene->addChild(_terrain);
287 _worldScene->addChild(_player);
288 _worldScene->addChild(_monsters[0]);
289 _worldScene->addChild(_monsters[1]);
290 // move camera above player
291 ca->setPosition3D(_player->getPosition3D()+Vec3(0, 45, 60));
292 ca->setRotation3D(Vec3(-45,0,0));
293 _worldScene->setPosition3D(s_scenePositons[SCENE_WORLD]);
294 this->addChild(_worldScene);
295
297 // test scene is UI scene, use default camera
298 // use the default camera to look 2D base UI layer
299 ca = _gameCameras[CAMERA_UI_2D] = this->getDefaultCamera();
300 ca->setDepth(CAMERA_UI_2D);
301 ca->setName(s_CameraNames[CAMERA_UI_2D]);
302 // create UI element and add to ui scene
303 createUI();
304 this->addChild(_ui);
305
307 // create dialog scene, this scene has two dialog and three cameras
308 _dlgScene = Node::create();
309 // use default camera to render the base 2D elements
310 ca = _gameCameras[CAMERA_DIALOG_2D_BASE] = Camera::create();
311 ca->setDepth(CAMERA_DIALOG_2D_BASE);
313 _dlgScene->addChild(ca);
314 // create a camera to look the 3D model in dialog scene
315 ca = _gameCameras[CAMERA_DIALOG_3D_MODEL] = Camera::create();
316 ca->setDepth(CAMERA_DIALOG_3D_MODEL);
318 ca->setCameraFlag(s_CF[LAYER_MIDDLE]);
319 _dlgScene->addChild(ca);
320 // create a camera to look the UI element over on the 3D models
321 ca = _gameCameras[CAMERA_DIALOG_2D_ABOVE] = Camera::create();
322 ca->setDepth(CAMERA_DIALOG_2D_ABOVE);
324 ca->setCameraFlag(s_CF[LAYER_TOP]);
325 _dlgScene->addChild(ca);
326 // create dialogs and add to dialog scene
328 _dlgScene->addChild(_playerDlg);
330 _dlgScene->addChild(_detailDlg);
331 // add dialog scene to test scene, which can't see the other element
332 _dlgScene->setPosition3D(s_scenePositons[SCENE_DIALOG]);
333 this->addChild(_dlgScene);
334
336 // create description scene, this scene has a dialog and three cameras
337 _osdScene = Node::create();
338 // use default camera for render 2D element
339 ca = _gameCameras[CAMERA_OSD_2D_BASE] = Camera::create();
340 ca->setDepth(CAMERA_OSD_2D_BASE);
341 ca->setName(s_CameraNames[CAMERA_OSD_2D_BASE]);
342 _osdScene->addChild(ca);
343 // create a camera to look the 3D model in dialog scene
344 ca = _gameCameras[CAMERA_OSD_3D_MODEL] = Camera::create();
345 ca->setDepth(CAMERA_OSD_3D_MODEL);
347 ca->setCameraFlag(s_CF[LAYER_MIDDLE]);
348 _osdScene->addChild(ca);
349 // create a camera to look the UI element over on the 3D models
350 ca = _gameCameras[CAMERA_OSD_2D_ABOVE] = Camera::create();
351 ca->setDepth(CAMERA_OSD_2D_ABOVE);
353 ca->setCameraFlag(s_CF[LAYER_TOP]);
354 _osdScene->addChild(ca);
355 // create desc dialog and add to osd scene
357 _osdScene->addChild(_descDlg);
358 // add osd scene to test scene, which can't see the other elements
359 _osdScene->setPosition3D(s_scenePositons[SCENE_OSD]);
360 this->addChild(_osdScene);
361
362 _playerDlg->setVisible(false);
363 _detailDlg->setVisible(false);
364 _descDlg->setVisible(false);
365
367 // add touch event callback
368 auto listener = EventListenerTouchOneByOne::create();
369 listener->onTouchBegan = CC_CALLBACK_2(Scene3DTestScene::onTouchBegan, this);
370 listener->onTouchEnded = CC_CALLBACK_2(Scene3DTestScene::onTouchEnd, this);
371 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
372
373 ret = true;
374 } while (0);
375
376 return ret;
377}
378
380{
381 // create skybox
382 //create and set our custom shader
383 auto shader = GLProgram::createWithFilenames("Sprite3DTest/cube_map.vert",
384 "Sprite3DTest/cube_map.frag");
385 auto state = GLProgramState::create(shader);
386
387 // create the second texture for cylinder
388 _textureCube = TextureCube::create("Sprite3DTest/skybox/left.jpg",
389 "Sprite3DTest/skybox/right.jpg",
390 "Sprite3DTest/skybox/top.jpg",
391 "Sprite3DTest/skybox/bottom.jpg",
392 "Sprite3DTest/skybox/front.jpg",
393 "Sprite3DTest/skybox/back.jpg");
394 //set texture parameters
395 Texture2D::TexParams tRepeatParams;
396 tRepeatParams.magFilter = GL_LINEAR;
397 tRepeatParams.minFilter = GL_LINEAR;
398 tRepeatParams.sAddressMode = GL_MIRRORED_REPEAT;
399 tRepeatParams.tAddressMode = GL_MIRRORED_REPEAT;
400 _textureCube->setTexParameters(tRepeatParams);
401
402 // pass the texture sampler to our custom shader
403 state->setUniformTexture("u_cubeTex", _textureCube);
404
405 // add skybox
406 _skyBox = Skybox::create();
407 _skyBox->setCameraMask(s_CM[LAYER_BACKGROUND]);
408 _skyBox->setTexture(_textureCube);
409
410 // create terrain
411 Terrain::DetailMap r("TerrainTest/dirt.jpg");
412 Terrain::DetailMap g("TerrainTest/Grass2.jpg",10);
413 Terrain::DetailMap b("TerrainTest/road.jpg");
414 Terrain::DetailMap a("TerrainTest/GreenSkin.jpg",20);
415 Terrain::TerrainData data("TerrainTest/heightmap16.jpg",
416 "TerrainTest/alphamap.png",
417 r,g,b,a,Size(32,32),40.0f,2);
418 _terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
419 _terrain->setMaxDetailMapAmount(4);
420 _terrain->setDrawWire(false);
421
422 _terrain->setSkirtHeightRatio(3);
423 _terrain->setLODDistance(64,128,192);
424
425 // create player
426 _player = Player::create("Sprite3DTest/girl.c3b",
428 _terrain);
429 _player->setScale(0.08f);
430 _player->setPositionY(_terrain->getHeight(_player->getPositionX(),
431 _player->getPositionZ()));
432
433 auto animation = Animation3D::create("Sprite3DTest/girl.c3b","Take 001");
434 if (animation)
435 {
436 auto animate = Animate3D::create(animation);
437 _player->runAction(RepeatForever::create(animate));
438 }
439 // add a particle 3d above player
440 auto rootps =
441 PUParticleSystem3D::create("Particle3D/scripts/blackHole.pu",
442 "Particle3D/materials/pu_mediapack_01.material");
443 rootps->setScale(2);
444 rootps->setPosition3D(Vec3(0, 150, 0));
445 auto moveby = MoveBy::create(2.0f, Vec2(50.0f, 0.0f));
446 auto moveby1 = MoveBy::create(2.0f, Vec2(-50.0f, 0.0f));
447 rootps->runAction(RepeatForever::create(Sequence::create(moveby, moveby1, nullptr)));
448 rootps->startParticleSystem();
449
450 _player->addChild(rootps, 0);
451
452 // add BillBoard for test blend
453 auto billboard = BillBoard::create("Images/btn-play-normal.png");
454 billboard->setPosition3D(Vec3(0,180,0));
455 _player->addChild(billboard);
456
457 // create two Sprite3D monster, one is transparent
458 auto monster = Sprite3D::create("Sprite3DTest/orc.c3b");
459 monster->setRotation3D(Vec3(0,180,0));
460 monster->setPosition3D(_player->getPosition3D() + Vec3(50, -10, 0));
461 monster->setOpacity(128);
462 _monsters[0] = monster;
463 monster = Sprite3D::create("Sprite3DTest/orc.c3b");
464 monster->setRotation3D(Vec3(0,180,0));
465 monster->setPosition3D(_player->getPosition3D() + Vec3(-50, -5, 0));
466 _monsters[1] = monster;
467}
468
470{
471 _ui = Layer::create();
472
473 // first, add menu to ui
474 // create player button
475 auto showPlayerDlgItem = MenuItemImage::create("Images/Pea.png",
476 "Images/Pea.png",
477 [this](Ref* sender){
478 this->_playerDlg->setVisible(!this->_playerDlg->isVisible());
479 });
480 showPlayerDlgItem->setName("showPlayerDlgItem");
481 showPlayerDlgItem->setPosition(VisibleRect::left().x + 30, VisibleRect::top().y - 30);
482
483 // create description button
484 TTFConfig ttfConfig("fonts/arial.ttf", 20);
485 auto descItem = MenuItemLabel::create(Label::createWithTTF(ttfConfig, "Description"),
486 [this](Ref* sender)
487 {
488 if (this->_descDlg->isVisible())
489 {
490 // hide descDlg
491 _descDlg->setVisible(false);
492 }
493 else
494 {
495 // animate show descDlg
496 _descDlg->setVisible(true);
497 _descDlg->setScale(0);
498 _descDlg->runAction(ScaleTo::create(2, 1.0));
499 }
500 });
501 descItem->setName("descItem");
502 descItem->setPosition(Vec2(VisibleRect::right().x - 50, VisibleRect::top().y - 25));
503
504 auto menu = Menu::create(showPlayerDlgItem,
505 descItem,
506 nullptr);
507 menu->setPosition(Vec2::ZERO);
508 _ui->addChild(menu);
509
510 // second, add cameras control button to ui
511 auto createCameraButton = [this](int tag, const char* text)-> Node *
512 {
513 auto cb = ui::CheckBox::create("cocosui/check_box_normal.png",
514 "cocosui/check_box_normal_press.png",
515 "cocosui/check_box_active.png",
516 "cocosui/check_box_normal_disable.png",
517 "cocosui/check_box_active_disable.png");
518 cb->setTag(tag);
519 cb->setSelected(true);
520 if (text) cb->setName(text);
521 cb->setAnchorPoint(Vec2(0, 0.5));
522 cb->setScale(0.8f);
523 cb->addClickEventListener([this](Ref* sender)
524 {
525 auto index = static_cast<Node *>(sender)->getTag();
526 auto camera = this->_gameCameras[index];
527 camera->setVisible(!camera->isVisible());
528 });
529 if (text)
530 {
531 auto label = ui::Text::create();
532 label->setString(text);
533 label->setAnchorPoint(Vec2(0, 0));
534 label->setPositionX(cb->getContentSize().width);
535 cb->addChild(label);
536 }
537 return cb;
538 };
539
540 Vec2 pos = VisibleRect::leftBottom();
541 pos.y += 30;
542 float stepY = 25;
543 for (int i = CAMERA_COUNT - 1; i >= 0; --i)
544 {
545 // if hide CAMERA_UI_2D, the menu won't show again
546 // so skip it
547 if (CAMERA_UI_2D == i)
548 {
549 continue;
550 }
551 auto cameraBtn = createCameraButton(i, s_CameraNames[i]);
552 cameraBtn->setPosition(pos);
553 _ui->addChild(cameraBtn);
554 pos.y += stepY;
555 }
556 auto labelCameras = ui::Text::create();
557 labelCameras->setString("Cameras");
558 labelCameras->setAnchorPoint(Vec2(0, 0));
559 labelCameras->setPosition(pos);
560 _ui->addChild(labelCameras);
561}
562
564{
565 SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_ui_plist);
566
567 Size dlgSize(190, 240);
568 Vec2 pos = VisibleRect::center();
569 float margin = 10;
570
571 // first, create dialog ui part, include background, title and buttons
572 _playerDlg = ui::Scale9Sprite::createWithSpriteFrameName("button_actived.png");
573 _playerDlg->setContentSize(dlgSize);
574 _playerDlg->setAnchorPoint(Vec2(1, 0.5));
575 pos.y -= margin;
576 pos.x -= margin;
577 _playerDlg->setPosition(pos);
578
579 // title
580 auto title = Label::createWithTTF("Player Dialog","fonts/arial.ttf",16);
581 title->setPosition(dlgSize.width / 2, dlgSize.height - margin * 2);
582 _playerDlg->addChild(title);
583
584 // player background
585 Size bgSize(110, 180);
586 Vec2 bgPos(margin, dlgSize.height / 2 - margin);
587 auto playerBg = ui::Scale9Sprite::createWithSpriteFrameName("item_bg.png");
588 playerBg->setContentSize(bgSize);
589 playerBg->setAnchorPoint(Vec2(0, 0.5));
590 playerBg->setPosition(bgPos);
591 _playerDlg->addChild(playerBg);
592
593 // item background and item
594 Size itemSize(48, 48);
595 Vec2 itemAnchor(0, 1);
596 Vec2 itemPos(bgPos.x + bgSize.width + margin, bgPos.y + bgSize.height / 2);
597 auto itemBg = ui::Scale9Sprite::createWithSpriteFrameName("item_bg.png");
598 itemBg->setContentSize(itemSize);
599 itemBg->setAnchorPoint(itemAnchor);
600 itemBg->setPosition(itemPos);
601 _playerDlg->addChild(itemBg);
602
603 auto item = ui::Button::create("crystal.png", "", "", ui::Widget::TextureResType::PLIST);
604 item->setTitleText("Crystal");
605 item->setScale(1.5);
606 item->setAnchorPoint(itemAnchor);
607 item->setPosition(itemPos);
608 item->addClickEventListener([this](Ref* sender){
609 this->_detailDlg->setVisible(!this->_detailDlg->isVisible());
610 });
611 _playerDlg->addChild(item);
612
613 // second, add 3d actor, which on dialog layer
614 std::string filename = "Sprite3DTest/girl.c3b";
615 auto girl = Sprite3D::create(filename);
616 girl->setScale(0.5);
617 girl->setPosition(bgSize.width / 2, margin * 2);
618 girl->setCameraMask(s_CM[LAYER_MIDDLE]);
619 playerBg->addChild(girl);
620
621 // third, add zoom in/out button, which is 2d ui element and over 3d actor
622 ui::Button* zoomIn = ui::Button::create("cocosui/animationbuttonnormal.png",
623 "cocosui/animationbuttonpressed.png");
624 zoomIn->setScale(0.5);
625 zoomIn->setAnchorPoint(Vec2(1, 1));
626 zoomIn->setPosition(Vec2(bgSize.width / 2 - margin / 2, bgSize.height - margin));
627 zoomIn->addClickEventListener([girl](Ref* sender){
628 girl->setScale(girl->getScale() * 2);
629 });
630 zoomIn->setTitleText("Zoom In");
631 zoomIn->setName("Zoom In");
632 zoomIn->setCameraMask(s_CM[LAYER_TOP]);
633 playerBg->addChild(zoomIn);
634
635 ui::Button* zoomOut = ui::Button::create("cocosui/animationbuttonnormal.png",
636 "cocosui/animationbuttonpressed.png");
637 zoomOut->setScale(0.5);
638 zoomOut->setAnchorPoint(Vec2(0, 1));
639 zoomOut->setPosition(Vec2(bgSize.width / 2 + margin / 2, bgSize.height - margin));
640 zoomOut->addClickEventListener([girl](Ref* sender){
641 girl->setScale(girl->getScale() / 2);
642 });
643 zoomOut->setTitleText("Zoom Out");
644 zoomOut->setName("Zoom Out");
645 zoomOut->setCameraMask(s_CM[LAYER_TOP]);
646 playerBg->addChild(zoomOut);
647
648 // forth, add slider bar
649 ui::Slider* slider = ui::Slider::create("cocosui/slidbar.png", "cocosui/sliderballnormal.png");
650 slider->setScale9Enabled(true);
651 slider->setPosition(Vec2(bgSize.width / 2, margin));
652 slider->setContentSize(Size(bgSize.width - margin, slider->getContentSize().height));
653 slider->addEventListener([girl, slider](Ref* sender,ui::Slider::EventType type)
654 {
655 girl->setRotation3D(Vec3(0, 360 * slider->getPercent() / 100, 0));
656 });
657 slider->setName("Slider");
658 slider->setCameraMask(s_CM[LAYER_TOP]);
659 playerBg->addChild(slider);
660}
661
663{
664 SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_ui_plist);
665
666 Size dlgSize(190, 240);
667 Vec2 pos = VisibleRect::center();
668 float margin = 10;
669
670 // create dialog
671 // use Scale9Sprite as background, it won't swallow touch event
672 _detailDlg = ui::Scale9Sprite::createWithSpriteFrameName("button_actived.png");
673 _detailDlg->setContentSize(dlgSize);
674 _detailDlg->setAnchorPoint(Vec2(0, 0.5));
675 _detailDlg->setOpacity(224);
676 pos.y -= margin;
677 pos.x += margin;
678 _detailDlg->setPosition(pos);
679
680 // title
681 auto title = Label::createWithTTF("Detail Dialog","fonts/arial.ttf",16);
682 title->setPosition(dlgSize.width / 2, dlgSize.height - margin * 2);
683 _detailDlg->addChild(title);
684
685
686 // add capture screen buttons
687 ui::Button* capture = ui::Button::create("cocosui/animationbuttonnormal.png",
688 "cocosui/animationbuttonpressed.png");
689 capture->setScale(0.5);
690 capture->setAnchorPoint(Vec2(0.5, 0));
691 capture->setPosition(Vec2(dlgSize.width / 3, margin));
692 capture->addClickEventListener([this](Ref* sender)
693 {
694 Director::getInstance()->getTextureCache()->removeTextureForKey(_snapshotFile);
695 _osdScene->removeChildByTag(SNAPSHOT_TAG);
696 _snapshotFile = "CaptureScreenTest.png";
697 utils::captureScreen([this](bool succeed, const std::string& outputFile)
698 {
699 if (!succeed)
700 {
701 log("Capture screen failed.");
702 return;
703 }
704 auto sp = Sprite::create(outputFile);
705 _osdScene->addChild(sp, 0, SNAPSHOT_TAG);
706 Size s = Director::getInstance()->getWinSize();
707 sp->setPosition(s.width / 2, s.height / 2);
708 sp->setScale(0.25);
709 _snapshotFile = outputFile;
710 }, _snapshotFile);
711 });
712 capture->setTitleText("Take Snapshot");
713 capture->setName("Take Snapshot");
714 _detailDlg->addChild(capture);
715
716 ui::Button* remove = ui::Button::create("cocosui/animationbuttonnormal.png",
717 "cocosui/animationbuttonpressed.png");
718 remove->setScale(0.5);
719 remove->setAnchorPoint(Vec2(0.5, 0));
720 remove->setPosition(Vec2(dlgSize.width * 2 / 3, margin));
721 remove->addClickEventListener([this](Ref* sender)
722 {
723 _osdScene->removeChildByTag(SNAPSHOT_TAG);
724 });
725 remove->setTitleText("Del Snapshot");
726 remove->setName("Del Snapshot");
727 _detailDlg->addChild(remove);
728
729 // add a spine ffd animation on it
730 auto skeletonNode =
731 SkeletonAnimationCullingFix::createWithFile("spine/goblins-pro.json", "spine/goblins.atlas", 1.5f);
732 skeletonNode->setAnimation(0, "walk", true);
733 skeletonNode->setSkin("goblin");
734
735 skeletonNode->setScale(0.25);
736 Size windowSize = Director::getInstance()->getWinSize();
737 skeletonNode->setPosition(Vec2(dlgSize.width / 2, remove->getContentSize().height / 2 + 2 * margin));
738 _detailDlg->addChild(skeletonNode);
739}
740
742{
743 SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_ui_plist);
744
745 Size dlgSize(440, 240);
746 Vec2 pos = VisibleRect::center();
747 float margin = 10;
748
749 // first, create dialog, add title and description text on it
750 // use Layout, which setTouchEnabled(true), as background, it will swallow touch event
751 auto desdDlg = ui::Layout::create();
752 desdDlg->setBackGroundImageScale9Enabled(true);
753 desdDlg->setBackGroundImage("button_actived.png", ui::Widget::TextureResType::PLIST);
754 desdDlg->setContentSize(dlgSize);
755 desdDlg->setAnchorPoint(Vec2(0.5f, 0.5f));
756 desdDlg->setOpacity(224);
757 desdDlg->setPosition(pos);
758 desdDlg->setTouchEnabled(true);
759 _descDlg = desdDlg;
760
761
762 // title
763 auto title = Label::createWithTTF("Description Dialog","fonts/arial.ttf",16);
764 title->setPosition(dlgSize.width / 2, dlgSize.height - margin * 2);
765 _descDlg->addChild(title);
766
767 // add a label to retain description text
768 Size textSize(400, 220);
769 Vec2 textPos(margin, dlgSize.height - (20 + margin));
770 std::string desc = std::string(
771 " Scene 3D test for 2D and 3D mix rendering.\n"
772 "- Game world composite with terrain, skybox and 3D objects.\n"
773 "- UI composite with 2D nodes.\n"
774 "- Click the icon at the topleft conner, will show a player dialog which "
775 "there is a 3D sprite on it.\n"
776 "- There are two button to zoom the player model, which should keep above "
777 "on 3D model.\n"
778 " - This description dialog should above all other elements.\n"
779 "\n"
780 " Game scene composite with root scene and three sub scene. These scene "
781 " located at different location, they can't see each other.\n"
782 "- Root scene contains ui layer\n"
783 "- World scene contains skybox and 3d scene.\n"
784 "- Dialog scene contains actor dialog and detail dialog.\n"
785 "- OSD scene contains description dialog.\n"
786 "\n"
787 "Click \"Description\" button to hide this dialog.\n");
788 auto text = Label::createWithSystemFont(desc, "", 9, textSize);
789 text->setAnchorPoint(Vec2(0, 1));
790 text->setPosition(textPos);
791 _descDlg->addChild(text);
792
793 // second, add a 3D model
794 std::string fileName = "Sprite3DTest/ReskinGirl.c3b";
795 Vec2 girlPos(textPos.x + textSize.width - 40, margin);
796 _reskinGirl = Sprite3D::create(fileName);
797 _reskinGirl->setCameraMask(s_CM[LAYER_MIDDLE]);
798 _reskinGirl->setScale(2.5);
799 _reskinGirl->setPosition(girlPos);
800 _descDlg->addChild(_reskinGirl);
801 auto animation = Animation3D::create(fileName);
802 if (animation)
803 {
804 auto animate = Animate3D::create(animation);
805
806 _reskinGirl->runAction(RepeatForever::create(animate));
807 }
808
809 auto& body = _skins[(int)SkinType::UPPER_BODY];
810 body.push_back("Girl_UpperBody01");
811 body.push_back("Girl_UpperBody02");
812
813 auto& pants = _skins[(int)SkinType::PANTS];
814 pants.push_back("Girl_LowerBody01");
815 pants.push_back("Girl_LowerBody02");
816
817 auto& shoes = _skins[(int)SkinType::SHOES];
818 shoes.push_back("Girl_Shoes01");
819 shoes.push_back("Girl_Shoes02");
820
821 auto& hair = _skins[(int)SkinType::HAIR];
822 hair.push_back("Girl_Hair01");
823 hair.push_back("Girl_Hair02");
824
825 auto& face = _skins[(int)SkinType::FACE];
826 face.push_back("Girl_Face01");
827 face.push_back("Girl_Face02");
828
829 auto& hand = _skins[(int)SkinType::HAND];
830 hand.push_back("Girl_Hand01");
831 hand.push_back("Girl_Hand02");
832
833 auto& glasses = _skins[(int)SkinType::GLASSES];
834 glasses.push_back("");
835 glasses.push_back("Girl_Glasses01");
836
837 memset(_curSkin, 0, (int)SkinType::MAX_TYPE * sizeof(int));
838
839 auto applyCurSkin = [this]()
840 {
841 for (ssize_t i = 0; i < this->_reskinGirl->getMeshCount(); i++) {
842 auto mesh = this->_reskinGirl->getMeshByIndex(static_cast<int>(i));
843 bool isVisible = false;
844 for (int j = 0; j < (int)SkinType::MAX_TYPE; j++) {
845 if (mesh->getName() == _skins[j].at(_curSkin[j]))
846 {
847 isVisible = true;
848 break;
849 }
850 }
851 this->_reskinGirl->getMeshByIndex(static_cast<int>(i))->setVisible(isVisible);
852 }
853 };
854 applyCurSkin();
855
856 // third, add reskin buttons above 3D model
857 static const std::string btnTexts[SkinType::MAX_TYPE] =
858 {
859 "Hair",
860 "Glasses",
861 "Face",
862 "Coat",
863 "Hand",
864 "Pants",
865 "Shoes",
866 };
867 Vec2 btnPos(dlgSize.width - margin, margin);
868 for (int i = SkinType::MAX_TYPE - 1; i >= 0; --i) {
869 auto btn = ui::Button::create("cocosui/animationbuttonnormal.png",
870 "cocosui/animationbuttonpressed.png");
871 btn->setScale(0.5);
872 btn->setTag(i);
873 btn->setAnchorPoint(Vec2(1, 0));
874 btn->setPosition(btnPos);
875 btnPos.y += 20;
876 btn->addClickEventListener([this, applyCurSkin](Ref* sender)
877 {
878 auto index = static_cast<Node *>(sender)->getTag();
879 if (index < SkinType::MAX_TYPE)
880 {
881 _curSkin[index] = (_curSkin[index] + 1) % _skins[index].size();
882 applyCurSkin();
883 }
884 });
885 btn->setTitleText(btnTexts[i]);
886 btn->setCameraMask(s_CM[LAYER_TOP]);
887 _descDlg->addChild(btn);
888 }
889}
890
891void Scene3DTestScene::onTouchEnd(Touch* touch, Event* event)
892{
893 auto location = touch->getLocation();
894 auto camera = _gameCameras[CAMERA_WORLD_3D_SCENE];
895 if(camera != Camera::getVisitingCamera())
896 {
897 return;
898 }
899
900 if(_player)
901 {
902 Vec3 nearP(location.x, location.y, 0.0f), farP(location.x, location.y, 1.0f);
903 // convert screen touch location to the world location on near and far plane
904 auto size = Director::getInstance()->getWinSize();
905 camera->unprojectGL(size, &nearP, &nearP);
906 camera->unprojectGL(size, &farP, &farP);
907 Vec3 dir = farP - nearP;
908 dir.normalize();
909 Vec3 collisionPoint;
910 bool isInTerrain = _terrain->getIntersectionPoint(Ray(nearP, dir), collisionPoint);
911 if (!isInTerrain)
912 {
913 _player->idle();
914 }
915 else
916 {
917 dir = collisionPoint - _player->getPosition3D();
918 dir.y = 0;
919 dir.normalize();
920 _player->_headingAngle = -1*acos(dir.dot(Vec3(0,0,-1)));
921 dir.cross(dir,Vec3(0,0,-1),&_player->_headingAxis);
922 _player->_targetPos=collisionPoint;
923 _player->forward();
924 }
925 }
926 event->stopPropagation();
927}
928
930// Implements Scene3DTests
931Scene3DTests::Scene3DTests()
932{
934}
#define ADD_TEST_CASE(__className__)
Definition: BaseTest.h:211
SCENE_LAYER
@ LAYER_BACKGROUND
@ LAYER_MIDDLE
@ LAYER_TOP
@ LAYER_DEFAULT
@ LAYER_COUNT
static const char * s_CameraNames[CAMERA_COUNT]
static Vec3 s_scenePositons[SCENE_COUNT]
static unsigned short s_CM[LAYER_COUNT]
static CameraFlag s_CF[LAYER_COUNT]
GAME_CAMERAS_ORDER
@ CAMERA_COUNT
@ CAMERA_UI_2D
@ CAMERA_DIALOG_2D_BASE
@ CAMERA_WORLD_3D_SCENE
@ CAMERA_OSD_3D_MODEL
@ CAMERA_OSD_2D_BASE
@ CAMERA_DIALOG_3D_MODEL
@ CAMERA_DIALOG_2D_ABOVE
@ CAMERA_OSD_2D_ABOVE
@ CAMERA_WORLD_3D_SKYBOX
USING_NS_CC
Definition: Scene3DTest.cpp:34
GAME_SCENE
@ SCENE_COUNT
@ SCENE_WORLD
@ SCENE_DIALOG
@ SCENE_UI
@ SCENE_OSD
cocos2d::Vec3 _targetPos
Definition: TerrainTest.h:73
static Player * create(const char *file, cocos2d::Camera *cam, cocos2d::Terrain *terrain)
float _headingAngle
Definition: TerrainTest.h:75
cocos2d::Vec3 _headingAxis
Definition: TerrainTest.h:76
void idle()
void forward()
bool onTouchBegan(Touch *touch, Event *event)
Definition: Scene3DTest.cpp:80
bool init() override
void onTouchEnd(Touch *, Event *)
std::vector< Camera * > _gameCameras
Definition: Scene3DTest.cpp:95
cocos2d::Sprite3D * _reskinGirl
CREATE_FUNC(Scene3DTestScene)
int _curSkin[(int) SkinType::MAX_TYPE]
std::string _snapshotFile
cocos2d::Terrain * _terrain
virtual ~Scene3DTestScene()
TextureCube * _textureCube
static const int SNAPSHOT_TAG
Node * _monsters[2]
std::vector< std::string > _skins[(int) SkinType::MAX_TYPE]
static SkeletonAnimationCullingFix * createWithFile(const std::string &skeletonDataFile, const std::string &atlasFile, float scale=1)
Definition: Scene3DTest.cpp:51
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) override
Definition: Scene3DTest.cpp:44
virtual std::string title() const
Definition: BaseTest.h:59
static cocos2d::Vec2 top()
Definition: VisibleRect.cpp:57
static cocos2d::Vec2 center()
Definition: VisibleRect.cpp:69
static cocos2d::Vec2 left()
Definition: VisibleRect.cpp:45
static cocos2d::Vec2 leftBottom()
Definition: VisibleRect.cpp:87
static cocos2d::Vec2 right()
Definition: VisibleRect.cpp:51
static const char s_s9s_ui_plist[]
Definition: testResource.h:70