PuzzleSDK
TerrainTest.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 "TerrainTest.h"
26
28
29TerrainTests::TerrainTests()
30{
34}
35
36Vec3 camera_offset(0, 45, 60);
37#define PLAYER_HEIGHT 0
38
40{
41 Size visibleSize = Director::getInstance()->getVisibleSize();
42
43 //use custom camera
44 _camera = Camera::createPerspective(60,visibleSize.width/visibleSize.height,0.1f,800);
45 _camera->setCameraFlag(CameraFlag::USER1);
46 _camera->setPosition3D(Vec3(-1,1.6f,4));
47 addChild(_camera);
48
49 Terrain::DetailMap r("TerrainTest/dirt.jpg"),g("TerrainTest/Grass2.jpg"),b("TerrainTest/road.jpg"),a("TerrainTest/GreenSkin.jpg");
50
51 Terrain::TerrainData data("TerrainTest/heightmap16.jpg","TerrainTest/alphamap.png",r,g,b,a);
52
53 _terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
54 _terrain->setLODDistance(3.2f,6.4f,9.6f);
55 _terrain->setMaxDetailMapAmount(4);
56 addChild(_terrain);
57 _terrain->setCameraMask(2);
58 _terrain->setDrawWire(false);
59 auto listener = EventListenerTouchAllAtOnce::create();
60 listener->onTouchesMoved = CC_CALLBACK_2(TerrainSimple::onTouchesMoved, this);
61 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
62// add Particle3D for test blend
63 auto rootps = PUParticleSystem3D::create("Particle3D/scripts/mp_torch.pu");
64 rootps->setCameraMask((unsigned short)CameraFlag::USER1);
65 rootps->startParticleSystem();
66
67 this->addChild(rootps, 0, 0);
68}
69
70std::string TerrainSimple::title() const
71{
72 return "Terrain with skirt";
73}
74
75std::string TerrainSimple::subtitle() const
76{
77 return "Drag to walkThru";
78}
79
80void TerrainSimple::onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
81{
82 float delta = Director::getInstance()->getDeltaTime();
83 auto touch = touches[0];
84 auto location = touch->getLocation();
85 auto PreviousLocation = touch->getPreviousLocation();
86 Point newPos = PreviousLocation - location;
87
88 Vec3 cameraDir;
89 Vec3 cameraRightDir;
90 _camera->getNodeToWorldTransform().getForwardVector(&cameraDir);
91 cameraDir.normalize();
92 cameraDir.y=0;
93 _camera->getNodeToWorldTransform().getRightVector(&cameraRightDir);
94 cameraRightDir.normalize();
95 cameraRightDir.y=0;
96 Vec3 cameraPos= _camera->getPosition3D();
97 cameraPos+=cameraDir*newPos.y*0.5*delta;
98 cameraPos+=cameraRightDir*newPos.x*0.5*delta;
99 _camera->setPosition3D(cameraPos);
100}
101
102
103std::string TerrainWalkThru::title() const
104{
105 return "Player walk around in terrain";
106}
107
108std::string TerrainWalkThru::subtitle() const
109{
110 return "touch to move";
111}
112
114{
115 auto listener = EventListenerTouchAllAtOnce::create();
116 listener->onTouchesBegan = CC_CALLBACK_2(TerrainWalkThru::onTouchesBegan, this);
117 listener->onTouchesEnded = CC_CALLBACK_2(TerrainWalkThru::onTouchesEnd, this);
118 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
119
120 Size visibleSize = Director::getInstance()->getVisibleSize();
121
122 //use custom camera
123 _camera = Camera::createPerspective(60,visibleSize.width/visibleSize.height,0.1f,200);
124 _camera->setCameraFlag(CameraFlag::USER1);
125 addChild(_camera);
126
127 Terrain::DetailMap r("TerrainTest/dirt.jpg"),g("TerrainTest/Grass2.jpg",10),b("TerrainTest/road.jpg"),a("TerrainTest/GreenSkin.jpg",20);
128
129 Terrain::TerrainData data("TerrainTest/heightmap16.jpg","TerrainTest/alphamap.png",r,g,b,a,Size(32,32),40.0f,2);
130 _terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
131 _terrain->setMaxDetailMapAmount(4);
132 _terrain->setCameraMask(2);
133 _terrain->setDrawWire(false);
134
135 _terrain->setSkirtHeightRatio(3);
136 _terrain->setLODDistance(64,128,192);
137 _player = Player::create("Sprite3DTest/girl.c3b",_camera,_terrain);
138 _player->setCameraMask(2);
139 _player->setScale(0.08f);
140 _player->setPositionY(_terrain->getHeight(_player->getPositionX(),_player->getPositionZ())+PLAYER_HEIGHT);
141
142 // add Particle3D for test blend
143 auto rootps = PUParticleSystem3D::create("Particle3D/scripts/mp_torch.pu");
144 rootps->setCameraMask((unsigned short)CameraFlag::USER1);
145 rootps->setScale(30.0f);
146 rootps->startParticleSystem();
147 _player->addChild(rootps);
148
149 // add BillBoard for test blend
150 auto billboard = BillBoard::create("Images/btn-play-normal.png");
151 billboard->setPosition3D(Vec3(0,180,0));
152 billboard->setCameraMask((unsigned short)CameraFlag::USER1);
153 _player->addChild(billboard);
154
155 auto animation = Animation3D::create("Sprite3DTest/girl.c3b","Take 001");
156 if (animation)
157 {
158 auto animate = Animate3D::create(animation);
159 _player->runAction(RepeatForever::create(animate));
160 }
161
162 _camera->setPosition3D(_player->getPosition3D()+camera_offset);
163 _camera->setRotation3D(Vec3(-45,0,0));
164
165 addChild(_player);
166 addChild(_terrain);
167}
168
169
170void TerrainWalkThru::onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
171{
172}
173
174void TerrainWalkThru::onTouchesEnd(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
175{
176 auto touch = touches[0];
177 auto location = touch->getLocationInView();
178 if(_camera)
179 {
180 if(_player)
181 {
182 Vec3 nearP(location.x, location.y, 0.0f), farP(location.x, location.y, 1.0f);
183
184 auto size = Director::getInstance()->getWinSize();
185 _camera->unproject(size, &nearP, &nearP);
186 _camera->unproject(size, &farP, &farP);
187 Vec3 dir = farP - nearP;
188 dir.normalize();
189 Vec3 collisionPoint(-999,-999,-999);
190 bool isInTerrain = _terrain->getIntersectionPoint(Ray(nearP, dir), collisionPoint);
191 if (!isInTerrain)
192 {
193 _player->idle();
194 return;
195 }
196 dir = collisionPoint - _player->getPosition3D();
197 dir.y = 0;
198 dir.normalize();
199 _player->_headingAngle = -1*acos(dir.dot(Vec3(0,0,-1)));
200 dir.cross(dir,Vec3(0,0,-1),&_player->_headingAxis);
201 _player->_targetPos=collisionPoint;
202 _player->forward();
203 }
204 }
205}
206
207
208bool Player::isDone() const
209{
210 return false;
211}
212
213
214void Player::update(float dt)
215{
216 auto player = (Sprite3D *)this;
217 switch (_playerState)
218 {
220 break;
222 {
223 Vec3 curPos= player->getPosition3D();
224 Vec3 newFaceDir = _targetPos - curPos;
225 newFaceDir.y = 0.0f;
226 newFaceDir.normalize();
227 Vec3 offset = newFaceDir * 25.0f * dt;
228 curPos+=offset;
229 player->setPosition3D(curPos);
230 }
231 break;
233 {
234 Vec3 forward_vec;
235 player->getNodeToWorldTransform().getForwardVector(&forward_vec);
236 forward_vec.normalize();
237 player->setPosition3D(player->getPosition3D()-forward_vec*15*dt);
238 }
239 break;
241 {
242 player->setRotation3D(player->getRotation3D()+Vec3(0,25*dt,0));
243 }
244 break;
246 {
247 player->setRotation3D(player->getRotation3D()+Vec3(0,-25*dt,0));
248 }
249 break;
250 default:
251 break;
252 }
253 // transform player position to world coord
254 auto playerPos = player->getPosition3D();
255 auto playerModelMat = player->getParent()->getNodeToWorldTransform();
256 playerModelMat.transformPoint(&playerPos);
257 Vec3 Normal;
258 float player_h = _terrain->getHeight(playerPos.x, playerPos.z,&Normal);
259 if (Normal.isZero())//check the player whether is out of the terrain
260 {
261 player_h = playerPos.y;
262 }
263 else
264 {
265 player_h += PLAYER_HEIGHT;
266 }
267 player->setPositionY(player_h);
268 Quaternion q2;
269 q2.createFromAxisAngle(Vec3(0,1,0),(float)-M_PI,&q2);
270
271 Quaternion headingQ;
272 headingQ.createFromAxisAngle(_headingAxis,_headingAngle,&headingQ);
273 player->setRotationQuat(headingQ*q2);
274 auto vec_offset =Vec4(camera_offset.x,camera_offset.y,camera_offset.z,1);
275 vec_offset = player->getNodeToWorldTransform()*vec_offset;
276 _cam->setPosition3D(player->getPosition3D() + camera_offset);
277 updateState();
278}
279
281{
283}
284
286{
288}
289
291{
293}
294
295
297{
299}
300
302{
304}
305
307{
308 auto player = (Sprite3D * )this;
309 switch (_playerState)
310 {
312 {
313 Vec2 player_pos =Vec2(player->getPositionX(),player->getPositionZ());
314 Vec2 targetPos = Vec2(_targetPos.x,_targetPos.z);
315 auto dist = player_pos.distance(targetPos);
316 if(dist<1)
317 {
319 }
320 }
321 break;
322 default:
323 break;
324 }
325}
326
327Player * Player::create(const char * file,Camera * cam,Terrain * terrain)
328{
329 //
330 auto sprite = new (std::nothrow) Player();
331 if (sprite && sprite->initWithFile(file))
332 {
333 sprite->_headingAngle = 0;
334 sprite->_playerState = PLAYER_STATE_IDLE;
335 sprite->_cam = cam;
336 sprite->_terrain = terrain;
337 sprite->autorelease();
338 sprite->scheduleUpdate();
339 return sprite;
340 }
341 CC_SAFE_DELETE(sprite);
342 return nullptr;
343}
344
346{
347 Size visibleSize = Director::getInstance()->getVisibleSize();
348
349 //use custom camera
350 _camera = Camera::createPerspective(60,visibleSize.width/visibleSize.height,0.1f,800);
351 _camera->setCameraFlag(CameraFlag::USER1);
352 _camera->setPosition3D(Vec3(-1,1.6f,4));
353 addChild(_camera);
354
355 Terrain::DetailMap r("TerrainTest/dirt.jpg"),g("TerrainTest/Grass2.jpg"),b("TerrainTest/road.jpg"),a("TerrainTest/GreenSkin.jpg");
356
357 Terrain::TerrainData data("TerrainTest/heightmap16.jpg","TerrainTest/alphamap.png",r,g,b,a);
358
359 _terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
360 _terrain->setLODDistance(3.2f,6.4f,9.6f);
361 _terrain->setMaxDetailMapAmount(4);
362 addChild(_terrain);
363 _terrain->setCameraMask(2);
364 _terrain->setDrawWire(false);
365 _terrain->setLightMap("TerrainTest/Lightmap.png");
366 auto listener = EventListenerTouchAllAtOnce::create();
367 listener->onTouchesMoved = CC_CALLBACK_2(TerrainWithLightMap::onTouchesMoved, this);
368 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
369
370}
371std::string TerrainWithLightMap::title() const
372{
373 return "Terrain using light map";
374}
376{
377 return "Drag to walkThru";
378}
379void TerrainWithLightMap::onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
380{
381 float delta = Director::getInstance()->getDeltaTime();
382 auto touch = touches[0];
383 auto location = touch->getLocation();
384 auto PreviousLocation = touch->getPreviousLocation();
385 Point newPos = PreviousLocation - location;
386
387 Vec3 cameraDir;
388 Vec3 cameraRightDir;
389 _camera->getNodeToWorldTransform().getForwardVector(&cameraDir);
390 cameraDir.normalize();
391 cameraDir.y=0;
392 _camera->getNodeToWorldTransform().getRightVector(&cameraRightDir);
393 cameraRightDir.normalize();
394 cameraRightDir.y=0;
395 Vec3 cameraPos= _camera->getPosition3D();
396 cameraPos+=cameraDir*newPos.y*0.5*delta;
397 cameraPos+=cameraRightDir*newPos.x*0.5*delta;
398 _camera->setPosition3D(cameraPos);
399}
#define ADD_TEST_CASE(__className__)
Definition: BaseTest.h:211
#define PLAYER_HEIGHT
Definition: TerrainTest.cpp:37
Vec3 camera_offset(0, 45, 60)
USING_NS_CC
Definition: TerrainTest.cpp:27
#define PLAYER_STATE_IDLE
Definition: TerrainTest.h:57
#define PLAYER_STATE_LEFT
Definition: TerrainTest.h:55
#define PLAYER_STATE_FORWARD
Definition: TerrainTest.h:58
#define PLAYER_STATE_RIGHT
Definition: TerrainTest.h:56
#define PLAYER_STATE_BACKWARD
Definition: TerrainTest.h:59
cocos2d::Terrain * _terrain
Definition: TerrainTest.h:78
cocos2d::Vec3 _targetPos
Definition: TerrainTest.h:73
static Player * create(const char *file, cocos2d::Camera *cam, cocos2d::Terrain *terrain)
void turnLeft()
virtual bool isDone() const
float _headingAngle
Definition: TerrainTest.h:75
void turnRight()
cocos2d::Vec3 _headingAxis
Definition: TerrainTest.h:76
void backward()
cocos2d::Camera * _cam
Definition: TerrainTest.h:79
void idle()
void updateState()
virtual void update(float dt)
void forward()
int _playerState
Definition: TerrainTest.h:80
virtual std::string title() const override
Definition: TerrainTest.cpp:70
void onTouchesMoved(const std::vector< cocos2d::Touch * > &touches, cocos2d::Event *event)
Definition: TerrainTest.cpp:80
cocos2d::Camera * _camera
Definition: TerrainTest.h:52
cocos2d::Terrain * _terrain
Definition: TerrainTest.h:50
virtual std::string subtitle() const override
Definition: TerrainTest.cpp:75
Player * _player
Definition: TerrainTest.h:96
void onTouchesEnd(const std::vector< cocos2d::Touch * > &touches, cocos2d::Event *event)
cocos2d::Camera * _camera
Definition: TerrainTest.h:94
virtual std::string title() const override
cocos2d::Terrain * _terrain
Definition: TerrainTest.h:95
void onTouchesBegan(const std::vector< cocos2d::Touch * > &touches, cocos2d::Event *event)
virtual std::string subtitle() const override
cocos2d::Terrain * _terrain
Definition: TerrainTest.h:109
virtual std::string title() const override
virtual std::string subtitle() const override
cocos2d::Camera * _camera
Definition: TerrainTest.h:110
void onTouchesMoved(const std::vector< cocos2d::Touch * > &touches, cocos2d::Event *event)