axmol/tests/js-tests/src/NavMeshTest/NavMeshTest.js

400 lines
14 KiB
JavaScript

var NavMeshTestIdx = -1;
var physicsScene = null;
var START_POS_X = -0.5;
var START_POS_Y = -2.5;
var START_POS_Z = -0.5;
var ARRAY_SIZE_X = 4;
var ARRAY_SIZE_Y = 3;
var ARRAY_SIZE_Z = 4;
var NavMeshTestScene = cc.Scene.extend({
ctor:function () {
this._super();
var label = new cc.LabelTTF("Main Menu", "Arial", 20);
var menuItem = new cc.MenuItemLabel(label, this.onMainMenuCallback, this);
var menu = new cc.Menu(menuItem);
menu.x = 0;
menu.y = 0;
menuItem.x = winSize.width - 50;
menuItem.y = 25;
this.addChild(menu);
this.initWithPhysics();
this.getPhysics3DWorld().setDebugDrawEnable(false);
physicsScene = this;
},
onMainMenuCallback:function () {
var scene = new cc.Scene();
var layer = new TestController();
scene.addChild(layer);
director.runScene(scene);
},
runThisTest:function (num) {
director.runScene(this);
}
});
var NavMeshBaseTestDemo = NavMeshTestScene.extend({
_title:"NavMesh Test",
_camera:null,
_needMoveAgents:null,
_agents:[],
_angle:null,
ctor:function () {
this._super();
this._agents = [];
this._angle = 0.0;
var size = cc.winSize;
this._camera = new cc.Camera(cc.Camera.Mode.PERSPECTIVE, 30.0, size.width / size.height, 1.0, 1000.0);
this._camera.setPosition3D(cc.math.vec3(0, 50, 100));
this._camera.lookAt(cc.math.vec3(0, 0, 0), cc.math.vec3(0, 1, 0));
this._camera.setCameraFlag(cc.CameraFlag.USER1);
this.addChild(this._camera);
cc.eventManager.addListener({
event:cc.EventListener.TOUCH_ALL_AT_ONCE,
onTouchesBegan:this.onTouchesBegan.bind(this),
onTouchesMoved:this.onTouchesMoved.bind(this),
onTouchesEnded:this.onTouchesEnded.bind(this)
}, this);
this.initScene();
this.scheduleUpdate();
},
initScene:function () {
//create mesh
var trianglesList = jsb.Bundle3D.getTrianglesList("NavMesh/scene.obj");
var rbDes = jsb.physics3DRigidBodyDes();
rbDes.mass = 0;
rbDes.shape = new jsb.Physics3DShape(jsb.Physics3DShape.ShapeType.MESH, trianglesList, trianglesList.length/3);
var rigidBody = new jsb.Physics3DRigidBody(rbDes);
var component = new jsb.Physics3DComponent(rigidBody);
var sprite = jsb.Sprite3D.create("NavMesh/scene.obj");
sprite.addComponent(component);
sprite.setCameraMask(cc.CameraFlag.USER1);
this.addChild(sprite);
physicsScene.setPhysics3DDebugCamera(this._camera);
var navMesh = jsb.NavMesh.create("NavMesh/all_tiles_tilecache.bin", "NavMesh/geomset.txt");
navMesh.setDebugDrawEnable(true);
physicsScene.setNavMesh(navMesh);
physicsScene.setNavMeshDebugCamera(this._camera);
var ambientLight = new jsb.AmbientLight(cc.color(64, 64, 64));
ambientLight.setCameraMask(cc.CameraFlag.USER1);
this.addChild(ambientLight);
var dirLight = new jsb.DirectionLight(cc.math.vec3(1.2, -1.1, 0.5), cc.color(255, 255, 255));
dirLight.setCameraMask(cc.CameraFlag.USER1);
this.addChild(dirLight);
},
onTouchesBegan:function(touches, event){
this._needMoveAgents = true;
return true;
},
onTouchesMoved:function(touches, event){
if(touches.length > 0 && this._camera){
var touch = touches[0];
var delta = touch.getDelta();
this._angle -= cc.degreesToRadians(delta.x);
this._camera.setPosition3D(cc.math.vec3(100*Math.sin(this._angle), 50, 100*Math.cos(this._angle)));
this._camera.lookAt(cc.math.vec3(0, 0, 0), cc.math.vec3(0, 1, 0));
if(delta.x * delta.x + delta.y + delta.y > 16)
this._needMoveAgents = false;
}
},
onTouchesEnded:function(touches, event){
if(!this._needMoveAgents)
return;
if(touches.length > 0){
var location = touches[0].getLocationInView();
var nearP = cc.math.vec3(location.x, location.y, -1);
var farP = cc.math.vec3(location.x, location.y, 1);
nearP = this._camera.unproject(nearP);
farP = this._camera.unproject(farP);
cc.log("ray cast before");
var result = physicsScene.getPhysics3DWorld().rayCast(nearP, farP);
cc.log("ray cast after");
this.moveAgents(result.hitPosition);
}
},
createAgent:function(pos){
var filePath = "Sprite3DTest/girl.c3b";
var param = jsb.navMeshAgentParam();
param.radius = 2.0;
param.height = 8.0;
param.maxSpeed = 8.0;
var agent = jsb.NavMeshAgent.create(param);
var agentNode = jsb.Sprite3D.create(filePath);
agent.setOrientationRefAxes(cc.math.vec3(-1.0, 0.0, 1.0));
var data = jsb.agentUserData();
agent.setUserData(data);
agentNode.setScale(0.05);
agentNode.addComponent(agent);
var node = new cc.Node();
node.addChild(agentNode);
node.setPosition3D(pos);
node.setCameraMask(cc.CameraFlag.USER1);
physicsScene.addChild(node);
var animation = new jsb.Animation3D(filePath);
var animate = new jsb.Animate3D(animation);
if (animate){
agentNode.runAction(new cc.RepeatForever(animate));
animate.setSpeed(0);
}
this._agents[this._agents.length] = {"agent":agent, "animate":animate};
},
createObstacle:function(pos){
var obstacle = jsb.NavMeshObstacle.create(2.0, 8.0);
var obstacleNode = jsb.Sprite3D.create("Sprite3DTest/cylinder.c3b");
obstacleNode.setPosition3D(cc.math.vec3(pos.x + 0.0, pos.y - 0.5, pos.z + 0.0));
obstacleNode.setRotation3D(cc.math.vec3(-90.0, 0.0, 0.0));
obstacleNode.setScale(0.3);
obstacleNode.addComponent(obstacle);
obstacleNode.setCameraMask(cc.CameraFlag.USER1);
this.addChild(obstacleNode);
},
jump:function(pV1, pV2, height, t){
var pOut = cc.math.vec3();
pOut.x = pV1.x + t * (pV2.x - pV1.x);
pOut.y = pV1.y + t * (pV2.y - pV1.y);
pOut.z = pV1.z + t * (pV2.z - pV1.z);
pOut.y += height * Math.sin(Math.PI * t);
return pOut;
},
moveAgents:function(des){
var self = this;
for (var index = 0; index < this._agents.length; index++){
var callback = function(agent, totalTimeAfterMove){
var data = agent.getUserData();
if (agent.isOnOffMeshLink()){
agent.setAutoTraverseOffMeshLink(false);
agent.setAutoOrientation(false);
var linkdata = agent.getCurrentOffMeshLinkData();
agent.getOwner().setPosition3D(self.jump(linkdata.startPosition, linkdata.endPosition, 10.0, data.time));
var dir = cc.math.vec3(linkdata.endPosition.x - linkdata.startPosition.x,
linkdata.endPosition.y - linkdata.startPosition.y, linkdata.endPosition.z - linkdata.startPosition.z);
dir.y = 0.0;
dir.normalize();
var axes;
var refAxes = cc.math.vec3(-1.0, 0.0, 1.0);
refAxes.normalize();
axes = cc.math.vec3Cross(refAxes, dir);
var angle = cc.math.vec3Dot(refAxes, dir);
agent.getOwner().setRotationQuat(cc.math.quaternion(axes, Math.acos(angle)));
data.time += 0.01;
if (1.0 < data.time){
agent.completeOffMeshLink();
agent.setAutoOrientation(true);
data.time = 0.0;
}
}
};
this._agents[index]["agent"].move(des, callback);
}
},
update:function(dt) {
this._super(dt);
if (!this._agents)
{
return;
}
for (var index = 0; index < this._agents.length; index++){
var speed = cc.math.vec3Length( this._agents[index]["agent"].getCurrentVelocity() ) * 0.2
this._agents[index]["animate"].setSpeed(0.0 < speed ? speed : 0.0)
}
},
//
// Menu
//
onEnter:function () {
this._super();
var label = new cc.LabelTTF(this._title, "Arial", 28);
this.addChild(label, 100, BASE_TEST_TITLE_TAG);
label.x = winSize.width / 2;
label.y = winSize.height - 50;
var label2 = new cc.LabelTTF(this._subtitle, "Thonburi", 16);
this.addChild(label2, 101, BASE_TEST_SUBTITLE_TAG);
label2.x = winSize.width / 2;
label2.y = winSize.height - 80;
var item1 = new cc.MenuItemImage(s_pathB1, s_pathB2, this.onBackCallback, this);
var item2 = new cc.MenuItemImage(s_pathR1, s_pathR2, this.onRestartCallback, this);
var item3 = new cc.MenuItemImage(s_pathF1, s_pathF2, this.onNextCallback, this);
item1.tag = BASE_TEST_MENUITEM_PREV_TAG;
item2.tag = BASE_TEST_MENUITEM_RESET_TAG;
item3.tag = BASE_TEST_MENUITEM_NEXT_TAG;
var menu = new cc.Menu(item1, item2, item3);
menu.x = 0;
menu.y = 0;
var width = item2.width, height = item2.height;
item1.x = winSize.width/2 - width*2;
item1.y = height/2 ;
item2.x = winSize.width/2;
item2.y = height/2 ;
item3.x = winSize.width/2 + width*2;
item3.y = height/2 ;
this.addChild(menu, 102, BASE_TEST_MENU_TAG);
},
onRestartCallback:function (sender) {
director.runScene(restartNavMeshTest());
},
onNextCallback:function (sender) {
director.runScene(nextNavMeshTest());
},
onBackCallback:function (sender) {
director.runScene(previousNavMeshTest());
}
});
var NavMeshBasicTestDemo = NavMeshBaseTestDemo.extend({
_title:"Navigation Mesh Test",
_subtitle:"Basic Test",
ctor:function () {
this._super();
var label = new cc.LabelTTF("DebugDraw OFF");
var menuItem = new cc.MenuItemLabel(label, function(){
var enabledDebug = physicsScene.getNavMesh().isDebugDrawEnabled();
physicsScene.getNavMesh().setDebugDrawEnable(!enabledDebug);
if (enabledDebug){
label.setString("Debug Draw ON");
}
else{
label.setString("Debug Draw OFF");
}
}, this);
var menu = new cc.Menu(menuItem);
menu.setPosition(cc.p(0, 0));
menuItem.setAnchorPoint(cc.p(0, 1));
menuItem.setPosition(cc.p(cc.visibleRect.left.x, cc.visibleRect.top.y - 50));
this.addChild(menu);
},
onEnter:function () {
this._super();
var result = physicsScene.getPhysics3DWorld().rayCast(cc.math.vec3(0, 50, 0), cc.math.vec3(0, -50, 0));
this.createAgent(result.hitPosition);
}
});
var NavMeshAdvanceTestDemo = NavMeshBaseTestDemo.extend({
_title:"Navigation Mesh Test",
_subtitle:"Advance Test",
ctor:function () {
this._super();
var label = new cc.LabelTTF();
var label2 = new cc.LabelTTF();
var label3 = new cc.LabelTTF();
var self = this;
var menuItem = new cc.MenuItemLabel(new cc.LabelTTF("Create Obstacle"), function(){
var x = Math.random() * 100 - 50;
var z = Math.random() * 100 - 50;
var result = physicsScene.getPhysics3DWorld().rayCast(cc.math.vec3(x, 50, z), cc.math.vec3(x, -50, z));
self.createObstacle(result.hitPosition);
}, this);
var menuItem2 = new cc.MenuItemLabel(new cc.LabelTTF("Create Agent"), function(){
var x = Math.random() * 100 - 50;
var z = Math.random() * 100 - 50;
var result = physicsScene.getPhysics3DWorld().rayCast(cc.math.vec3(x, 50, z), cc.math.vec3(x, -50, z));
self.createAgent(result.hitPosition);
}, this);
var label = new cc.LabelTTF("DebugDraw OFF");
var menuItem3 = new cc.MenuItemLabel(label, function(){
var enabledDebug = physicsScene.getNavMesh().isDebugDrawEnabled();
physicsScene.getNavMesh().setDebugDrawEnable(!enabledDebug);
if (enabledDebug){
label.setString("Debug Draw ON");
}
else{
label.setString("Debug Draw OFF");
}
}, this);
var menu = new cc.Menu(menuItem, menuItem2, menuItem3);
menu.setPosition(cc.p(0, 0));
menuItem.setAnchorPoint(cc.p(0, 1));
menuItem.setPosition(cc.p(cc.visibleRect.left.x, cc.visibleRect.top.y - 50));
menuItem2.setAnchorPoint(cc.p(0, 1));
menuItem2.setPosition(cc.p(cc.visibleRect.left.x, cc.visibleRect.top.y - 100));
menuItem3.setAnchorPoint(cc.p(0, 1));
menuItem3.setPosition(cc.p(cc.visibleRect.left.x, cc.visibleRect.top.y - 150));
this.addChild(menu);
},
onEnter:function () {
this._super();
var result = physicsScene.getPhysics3DWorld().rayCast(cc.math.vec3(0, 50, 0), cc.math.vec3(0, -50, 0));
this.createAgent(result.hitPosition);
}
});
//
// Flow control
//
var arrayOfNavMeshTest = [
NavMeshBasicTestDemo,
NavMeshAdvanceTestDemo
];
var nextNavMeshTest = function () {
NavMeshTestIdx++;
NavMeshTestIdx = NavMeshTestIdx % arrayOfNavMeshTest.length;
return new arrayOfNavMeshTest[NavMeshTestIdx ]();
};
var previousNavMeshTest = function () {
NavMeshTestIdx--;
if (NavMeshTestIdx < 0)
NavMeshTestIdx += arrayOfNavMeshTest.length;
return new arrayOfNavMeshTest[NavMeshTestIdx ]();
};
var restartNavMeshTest = function () {
return new arrayOfNavMeshTest[NavMeshTestIdx ]();
};