diff --git a/cocos/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp b/cocos/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp index ff636d65da..e7bf8b68af 100644 --- a/cocos/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp +++ b/cocos/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp @@ -6718,7 +6718,7 @@ static int lua_cocos2dx_GLProgramState_setVertexAttribPointer(lua_State* tolua_S unsigned int arg2; bool arg3; int arg4; - int arg5; + long arg5; ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.GLProgramState:setVertexAttribPointer"); @@ -6730,11 +6730,11 @@ static int lua_cocos2dx_GLProgramState_setVertexAttribPointer(lua_State* tolua_S ok &= luaval_to_int32(tolua_S, 6,(int *)&arg4, "cc.GLProgramState:setVertexAttribPointer"); - ok &= luaval_to_int32(tolua_S, 7, (int *)&arg5, "cc.GLProgramState:setVertexAttribPointer"); + ok &= luaval_to_long(tolua_S, 7, (long *)&arg5, "cc.GLProgramState:setVertexAttribPointer"); if(!ok) return 0; - cobj->setVertexAttribPointer(arg0, arg1, arg2, arg3, arg4, (void*)&arg5); + cobj->setVertexAttribPointer(arg0, arg1, arg2, arg3, arg4, (void*)arg5); lua_settop(tolua_S, 1); return 1; } @@ -7527,7 +7527,7 @@ static int tolua_cocos2d_Mat4_transformVector(lua_State* tolua_S) !tolua_isnumber(tolua_S, 3, 0, &tolua_err) || !tolua_isnumber(tolua_S, 4, 0, &tolua_err) || !tolua_isnumber(tolua_S, 5, 0, &tolua_err) || - !tolua_isnumber(tolua_S, 6, 0, &tolua_err)) + !tolua_istable(tolua_S, 6, 0, &tolua_err) ) goto tolua_lerror; else #endif @@ -7566,10 +7566,11 @@ static int tolua_cocos2d_Mat4_decompose(lua_State* tolua_S) { #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; + if (!tolua_istable(tolua_S, 1, 0, &tolua_err) || - !tolua_istable(tolua_S, 2, 0, &tolua_err) || - !tolua_istable(tolua_S, 3, 0, &tolua_err) || - !tolua_istable(tolua_S, 4, 0, &tolua_err)) + (!lua_isnil(tolua_S, 2) && !tolua_istable(tolua_S, 2, 0, &tolua_err)) || + (!lua_isnil(tolua_S, 3) && !tolua_istable(tolua_S, 3, 0, &tolua_err)) || + (!lua_isnil(tolua_S, 4) && !tolua_istable(tolua_S, 4, 0, &tolua_err)) ) goto tolua_lerror; else #endif @@ -7579,27 +7580,210 @@ static int tolua_cocos2d_Mat4_decompose(lua_State* tolua_S) cocos2d::Quaternion rotation; cocos2d::Vec3 translation; bool ok = true; + ok &= luaval_to_mat4(tolua_S, 1, &mat); if (!ok) return 0; - ok &= luaval_to_vec3(tolua_S, 2, &scale); - if (!ok) - return 0; + if (lua_isnil(tolua_S, 2) && !lua_isnil(tolua_S, 3) && !lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_quaternion(tolua_S, 3, &rotation); + if (!ok) + return 0; + - ok &= luaval_to_quaternion(tolua_S, 3, &rotation); - if (!ok) - return 0; + ok &= luaval_to_vec3(tolua_S, 4, &translation); + if (!ok) + return 0; + + + mat.decompose(nullptr, &rotation, &translation); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + quaternion_to_luaval(tolua_S, rotation); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + vec3_to_luaval(tolua_S, translation); + lua_rawset(tolua_S, -3); + + return 1; + } - ok &= luaval_to_vec3(tolua_S, 2, &translation); - if (!ok) - return 0; + if (lua_isnil(tolua_S, 2) && lua_isnil(tolua_S, 3) && !lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_vec3(tolua_S, 4, &translation); + if (!ok) + return 0; + + + mat.decompose(nullptr, nullptr, &translation); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + vec3_to_luaval(tolua_S, translation); + lua_rawset(tolua_S, -3); + + return 1; + } - mat.decompose(&scale, &rotation, &translation); - vec3_to_luaval(tolua_S, scale); - quaternion_to_luaval(tolua_S, rotation); - vec3_to_luaval(tolua_S, translation); - return 3; + if (!lua_isnil(tolua_S, 2) && lua_isnil(tolua_S, 3) && !lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_vec3(tolua_S, 2, &scale); + if (!ok) + return 0; + + ok &= luaval_to_vec3(tolua_S, 4, &translation); + if (!ok) + return 0; + + mat.decompose(&scale, nullptr, &translation); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + vec3_to_luaval(tolua_S, scale); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + vec3_to_luaval(tolua_S, translation); + lua_rawset(tolua_S, -3); + + return 1; + } + + if (!lua_isnil(tolua_S, 2) && lua_isnil(tolua_S, 3) && lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_vec3(tolua_S, 2, &scale); + if (!ok) + return 0; + + + mat.decompose(&scale, nullptr, nullptr); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + vec3_to_luaval(tolua_S, scale); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + return 1; + } + + if (!lua_isnil(tolua_S, 2) && !lua_isnil(tolua_S, 3) && lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_vec3(tolua_S, 2, &scale); + if (!ok) + return 0; + + ok &= luaval_to_quaternion(tolua_S, 3, &rotation); + if (!ok) + return 0; + + mat.decompose(&scale, &rotation, nullptr); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + vec3_to_luaval(tolua_S, scale); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + quaternion_to_luaval(tolua_S, rotation); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + return 1; + + } + + if (lua_isnil(tolua_S, 2) && !lua_isnil(tolua_S, 3) && lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_quaternion(tolua_S, 3, &rotation); + if (!ok) + return 0; + + mat.decompose(nullptr, &rotation, nullptr); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + quaternion_to_luaval(tolua_S, rotation); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + } + + if (!lua_isnil(tolua_S, 2) && !lua_isnil(tolua_S, 3) && !lua_isnil(tolua_S, 4)) + { + ok &= luaval_to_vec3(tolua_S, 2, &scale); + if (!ok) + return 0; + + ok &= luaval_to_quaternion(tolua_S, 3, &rotation); + if (!ok) + return 0; + + ok &= luaval_to_vec3(tolua_S, 4, &translation); + if (!ok) + return 0; + + mat.decompose(&scale, &rotation, &translation); + + lua_newtable(tolua_S); + + lua_pushstring(tolua_S, "scale"); + vec3_to_luaval(tolua_S, scale); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "rotation"); + quaternion_to_luaval(tolua_S, rotation); + lua_rawset(tolua_S, -3); + + lua_pushstring(tolua_S, "translation"); + lua_pushnil(tolua_S); + lua_rawset(tolua_S, -3); + + return 1; + } + + return 0; } return 0; #if COCOS2D_DEBUG >= 1 @@ -7617,7 +7801,7 @@ static int tolua_cocos2d_Vec3_cross(lua_State* tolua_S) tolua_Error tolua_err; #endif - if (1 == argc) + if (2 == argc) { #if COCOS2D_DEBUG >= 1 if (!tolua_istable(tolua_S, 1, 0, &tolua_err) || @@ -7687,6 +7871,38 @@ tolua_lerror: #endif } +static int tolua_cocos2d_Mat4_multiply(lua_State* tolua_S) +{ +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_istable(tolua_S, 1, 0, &tolua_err) || + !tolua_istable(tolua_S, 2, 0, &tolua_err) ) + goto tolua_lerror; + else +#endif + { + cocos2d::Mat4 mat1; + bool ok = luaval_to_mat4(tolua_S, 1, &mat1); + if(!ok) + return 0; + + cocos2d::Mat4 mat2; + ok = luaval_to_mat4(tolua_S, 2, &mat2); + if(!ok) + return 0; + + cocos2d::Mat4 ret = mat1 * mat2; + mat4_to_luaval(tolua_S, ret); + return 1; + } + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'mat4_multiply'.",&tolua_err); + return 0; +#endif +} + int register_all_cocos2dx_math_manual(lua_State* tolua_S) { if (nullptr == tolua_S) @@ -7698,6 +7914,7 @@ int register_all_cocos2dx_math_manual(lua_State* tolua_S) tolua_function(tolua_S, "mat4_getInversed", tolua_cocos2d_Mat4_getInversed); tolua_function(tolua_S, "mat4_transformVector", tolua_cocos2d_Mat4_transformVector); tolua_function(tolua_S, "mat4_decompose", tolua_cocos2d_Mat4_decompose); + tolua_function(tolua_S, "mat4_multiply", tolua_cocos2d_Mat4_multiply); tolua_function(tolua_S, "vec3_cross", tolua_cocos2d_Vec3_cross); tolua_endmodule(tolua_S); return 0; diff --git a/cocos/scripting/lua-bindings/script/cocos2d/Cocos2d.lua b/cocos/scripting/lua-bindings/script/cocos2d/Cocos2d.lua index 4eccc543e7..40663e766d 100644 --- a/cocos/scripting/lua-bindings/script/cocos2d/Cocos2d.lua +++ b/cocos/scripting/lua-bindings/script/cocos2d/Cocos2d.lua @@ -175,7 +175,7 @@ function cc.pIsSegmentIntersect(pt1,pt2,pt3,pt4) ret,s,t =cc.pIsLineIntersect(pt1, pt2, pt3, pt4,s,t) if ret and s >= 0.0 and s <= 1.0 and t >= 0.0 and t <= 0.0 then - return true; + return true end return false @@ -450,7 +450,6 @@ cc.mat4 = cc.mat4 or {} function cc.mat4.new(...) local params = {...} local size = #params - local obj = {} if 1 == size then @@ -463,10 +462,8 @@ function cc.mat4.new(...) end end elseif 16 == size then - if params[i] ~= nil then - mat4[i] = params[i] - else - mat4[i] = 0 + for i= 1, 16 do + obj[i] = params[i] end end @@ -482,3 +479,58 @@ end function cc.mat4.transformVector(self, vector, dst) return mat4_transformVector(self, vector, dst) end + +function cc.mat4.createIdentity() + return cc.mat4.new(1.0 ,0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0) +end + +function cc.mat4.createTranslation(translation, dst) + assert(type(translation) == "table" and type(dst) == "table", "The type of input parameters should be table") + dst = cc.mat4.createIdentity() + dst[13] = translation.x + dst[14] = translation.y + dst[15] = translation.z + return dst +end + +function cc.mat4.createRotation(q, dst) + assert(type(q) == "table" and type(dst) == "table", "The type of input parameters should be table") + local x2 = q.x + q.x + local y2 = q.y + q.y + local z2 = q.z + q.z + + local xx2 = q.x * x2 + local yy2 = q.y * y2 + local zz2 = q.z * z2 + local xy2 = q.x * y2 + local xz2 = q.x * z2 + local yz2 = q.y * z2 + local wx2 = q.w * x2 + local wy2 = q.w * y2 + local wz2 = q.w * z2 + + dst[1] = 1.0 - yy2 - zz2 + dst[2] = xy2 + wz2 + dst[3] = xz2 - wy2 + dst[4] = 0.0 + + dst[5] = xy2 - wz2 + dst[6] = 1.0 - xx2 - zz2 + dst[7] = yz2 + wx2 + dst[8] = 0.0 + + dst[9] = xz2 + wy2 + dst[10] = yz2 - wx2 + dst[11] = 1.0 - xx2 - yy2 + dst[12] = 0.0 + + dst[13] = 0.0 + dst[14] = 0.0 + dst[15] = 0.0 + dst[16] = 1.0 + + return dst +end diff --git a/tests/cpp-tests/Classes/Camera3DTest/Camera3DTest.cpp b/tests/cpp-tests/Classes/Camera3DTest/Camera3DTest.cpp index 54360e83aa..003d14462c 100644 --- a/tests/cpp-tests/Classes/Camera3DTest/Camera3DTest.cpp +++ b/tests/cpp-tests/Classes/Camera3DTest/Camera3DTest.cpp @@ -1194,6 +1194,7 @@ void CameraArcBallDemo::onTouchsMoved( const std::vector &touchs, Event Vec3 axes; float angle; calculateArcBall(axes, angle, prelocation.x, prelocation.y, location.x, location.y); //calculate rotation quaternion parameters + CCLOG("axes is %f, %f,%f,angle is %f",axes.x, axes.y, axes.z, angle); Quaternion quat(axes, angle); //get rotation quaternion _rotationQuat = quat * _rotationQuat; diff --git a/tests/lua-tests/src/Camera3DTest/Camera3DTest.lua b/tests/lua-tests/src/Camera3DTest/Camera3DTest.lua index 98a60968e0..f5f5b8d49b 100644 --- a/tests/lua-tests/src/Camera3DTest/Camera3DTest.lua +++ b/tests/lua-tests/src/Camera3DTest/Camera3DTest.lua @@ -23,7 +23,9 @@ local CameraType = local scheduler = cc.Director:getInstance():getScheduler() local Camera3DTestDemo = class("Camera3DTestDemo", function () - return cc.Layer:create() + local layer = cc.Layer:create() + Helper.initWithLayer(layer) + return layer end) function Camera3DTestDemo:ctor() @@ -451,10 +453,625 @@ function Camera3DTestDemo:init() end) end +local CameraRotationTest = class("CameraRotationTest", function () + local layer = cc.Layer:create() + Helper.initWithLayer(layer) + return layer +end) + +function CameraRotationTest:ctor() + -- body + self:init() +end + +function CameraRotationTest:init() + -- body + Helper.titleLabel:setString(self:title()) + Helper.subtitleLabel:setString(self:subtitle()) + self:registerScriptHandler(function (event) + if event == "enter" then + self:onEnter() + elseif event == "exit" then + self:onExit() + end + end) +end + +function CameraRotationTest:onEnter() + local s = cc.Director:getInstance():getWinSize() + + camControlNode = cc.Node:create() + camControlNode:setNormalizedPosition(cc.p(0.5, 0.5)) + self:addChild(camControlNode) + + camNode = cc.Node:create() + camNode:setPositionZ(cc.Camera:getDefaultCamera():getPosition3D().z) + camControlNode:addChild(camNode) + + local sp3d = cc.Sprite3D:create() + sp3d:setPosition(s.width/2, s.height/2) + self:addChild(sp3d) + + local lship = cc.Label:create() + lship:setString("Ship") + lship:setPosition(0, 20) + sp3d:addChild(lship) + + --Billboards + --Yellow is at the back + bill1 = cc.BillBoard:create("Images/Icon.png") + bill1:setPosition3D(cc.vec3(s.width/2 + 50, s.height/2 + 10, -10)) + bill1:setColor(cc.c3b(255, 255, 0)) + bill1:setScale(0.6) + self:addChild(bill1) + + l1 = cc.Label:create() + l1:setPosition(cc.p(0,-10)) + l1:setString("Billboard1") + l1:setColor(cc.c3b(255, 255, 255)) + l1:setScale(3) + bill1:addChild(l1) + + local p1 = cc.ParticleSystemQuad:create("Particles/SmallSun.plist") + p1:setPosition(30,80) + bill1:addChild(p1) + + bill2 = cc.BillBoard:create("Images/Icon.png") + bill2:setPosition3D(cc.vec3(s.width/2 - 50, s.height/2 - 10, 10)) + bill2:setScale(0.6) + self:addChild(bill2) + + l2 = cc.Label:create() + l2:setString("Billboard2") + l2:setPosition(cc.p(0,-10)) + l2:setColor(cc.c3b(255, 255, 255)) + l2:setScale(3) + bill2:addChild(l2) + + local p2 = cc.ParticleSystemQuad:create("Particles/SmallSun.plist") + p2:setPosition(30,80) + bill2:addChild(p2) + + --3D models + local model = cc.Sprite3D:create("Sprite3DTest/boss1.obj") + model:setScale(4) + model:setTexture("Sprite3DTest/boss.png") + model:setPosition3D(cc.vec3(s.width/2, s.height/2, 0)) + self:addChild(model) + + --Listener + lis = cc.EventListenerTouchOneByOne:create() + lis:registerScriptHandler(function (touch, event) + return true + end,cc.Handler.EVENT_TOUCH_BEGAN ) + + lis:registerScriptHandler(function (touch, event) + local dx = touch:getDelta().x + local rot = camControlNode:getRotation3D() + rot.y = rot.y + dx + camControlNode:setRotation3D(rot) + + local worldPos = cc.vec3(0.0, 0.0, 0.0) + local decompose = mat4_decompose(camNode:getNodeToWorldTransform(), nil ,nil, worldPos) + worldPos = decompose.translation + cc.Camera:getDefaultCamera():setPosition3D(worldPos) + cc.Camera:getDefaultCamera():lookAt(camControlNode:getPosition3D()) + end, cc.Handler.EVENT_TOUCH_MOVED) + + local eventDispatcher = self:getEventDispatcher() + eventDispatcher:addEventListenerWithSceneGraphPriority(lis, self) +end + +function CameraRotationTest:onExit() + +end + +function CameraRotationTest:title() + return "Camera Rotation Test" +end + +function CameraRotationTest:subtitle() + return "Slide to rotate" +end + +local FogTestDemo = class("FogTestDemo", function () + local layer = cc.Layer:create() + Helper.initWithLayer(layer) + return layer +end) + +function FogTestDemo:ctor() + -- body + self:init() +end + +function FogTestDemo:init() + -- body + self._layer3D = nil + self._cameraType = CameraType.FreeCamera + self._camera = nil + self._shader = nil + self._state = nil + + Helper.titleLabel:setString(self:title()) + Helper.subtitleLabel:setString(self:subtitle()) + + self:registerScriptHandler(function (event) + if event == "enter" then + self:onEnter() + elseif event == "exit" then + self:onExit() + end + end) +end + +function FogTestDemo:setEventListener() + local listener = cc.EventListenerTouchAllAtOnce:create() + + listener:registerScriptHandler(function(touches, event) + if #touches == 1 then + local touch = touches[1] + local prelocation = touch:getPreviousLocationInView() + local location = touch:getLocationInView() + local newPos = cc.p(prelocation.x - location.x, prelocation.y - location.y) + if self._cameraType == CameraType.FreeCamera then + + local transformMat = self._camera:getNodeToWorldTransform() + local cameraDir = { x = -transformMat[9], y = -transformMat[10], z = -transformMat[11] } + cameraDir = cc.vec3normalize(cameraDir) + cameraDir.y = 0 + + transformMat = self._camera:getNodeToWorldTransform() + local cameraRightDir = { x = transformMat[1], y = transformMat[2], z = transformMat[3]} + cameraRightDir = cc.vec3normalize(cameraRightDir) + cameraRightDir.y = 0 + + local cameraPos = self._camera:getPosition3D() + cameraPos = {x = cameraPos.x - cameraDir.x * newPos.y * 0.1, y = cameraPos.y - cameraDir.y * newPos.y * 0.1, z = cameraPos.z - cameraDir.z * newPos.y * 0.1} + cameraPos = {x = cameraPos.x + cameraRightDir.x * newPos.x * 0.1, y = cameraPos.y + cameraRightDir.y * newPos.x * 0.1, z = cameraPos.z + cameraRightDir.z * newPos.x * 0.1} + self._camera:setPosition3D(cameraPos) + + end + end + end, cc.Handler.EVENT_TOUCHES_MOVED) + + local eventDispatcher = self:getEventDispatcher() + eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self) +end + +function FogTestDemo:createMenu() + -- body + local ttfConfig = {} + ttfConfig.fontFilePath = "fonts/arial.ttf" + ttfConfig.fontSize = 20 + + local label1 = cc.Label:createWithTTF(ttfConfig,"Linear ") + local menuItem1 = cc.MenuItemLabel:create(label1) + menuItem1:registerScriptTapHandler(function (tag, sender ) + self._state:setUniformVec4("u_fogColor", cc.vec4(0.5,0.5,0.5,1.0)) + self._state:setUniformFloat("u_fogStart",10) + self._state:setUniformFloat("u_fogEnd",60) + self._state:setUniformInt("u_fogEquation" ,0) + + self._sprite3D1:setGLProgramState(self._state) + self._sprite3D2:setGLProgramState(self._state) + end) + + local label2 = cc.Label:createWithTTF(ttfConfig,"Exp") + local menuItem2 = cc.MenuItemLabel:create(label2) + menuItem2:registerScriptTapHandler(function (tag, sender ) + self._state:setUniformVec4("u_fogColor", cc.vec4(0.5,0.5,0.5,1.0)) + self._state:setUniformFloat("u_fogDensity",0.03) + self._state:setUniformInt("u_fogEquation" ,1) + + self._sprite3D1:setGLProgramState(self._state) + self._sprite3D2:setGLProgramState(self._state) + end) + local label3 = cc.Label:createWithTTF(ttfConfig,"Exp2") + local menuItem3 = cc.MenuItemLabel:create(label3) + menuItem3:registerScriptTapHandler(function (tag, sender ) + self._state:setUniformVec4("u_fogColor", cc.vec4(0.5,0.5,0.5,1.0)) + self._state:setUniformFloat("u_fogDensity",0.03) + self._state:setUniformInt("u_fogEquation" ,2) + + self._sprite3D1:setGLProgramState(self._state) + self._sprite3D2:setGLProgramState(self._state) + end) + local menu = cc.Menu:create(menuItem1, menuItem2, menuItem3) + + menu:setPosition(cc.p(0.0, 0.0)) + + menuItem1:setPosition(VisibleRect:left().x + 60, VisibleRect:top().y - 50) + menuItem2:setPosition(VisibleRect:left().x + 60, VisibleRect:top().y - 100) + menuItem3:setPosition(VisibleRect:left().x + 60, VisibleRect:top().y - 150) + self:addChild(menu, 0) +end + +function FogTestDemo:createLayer3D() + -- body + local s = cc.Director:getInstance():getWinSize() + + local layer3D = cc.Layer:create() + self:addChild(layer3D,0) + self._layer3D = layer3D + + self._shader = cc.GLProgram:createWithFilenames("Sprite3DTest/fog.vert","Sprite3DTest/fog.frag") + self._state = cc.GLProgramState:create(self._shader) + + self._sprite3D1 = cc.Sprite3D:create("Sprite3DTest/teapot.c3b") + self._sprite3D2 = cc.Sprite3D:create("Sprite3DTest/teapot.c3b") + + self._sprite3D1:setGLProgramState(self._state) + self._sprite3D2:setGLProgramState(self._state) + + --pass mesh's attribute to shader + local attributeNames = + { + "a_position", + "a_color", + "a_texCoord", + "a_texCoord1", + "a_texCoord2", + "a_texCoord3", + "a_normal", + "a_blendWeight", + "a_blendIndex", + } + + local offset = 0 + local attributeCount = self._sprite3D1:getMesh():getMeshVertexAttribCount() + for i = 1, attributeCount do + local meshattribute = self._sprite3D1:getMesh():getMeshVertexAttribute(i - 1) + self._state:setVertexAttribPointer(attributeNames[meshattribute.vertexAttrib + 1], + meshattribute.size, + meshattribute.type, + false, + self._sprite3D1:getMesh():getVertexSizeInBytes(), + offset) + offset = offset + meshattribute.attribSizeBytes + end + + local offset1 = 0 + local attributeCount1 = self._sprite3D2:getMesh():getMeshVertexAttribCount() + for i = 1, attributeCount1 do + local meshattribute = self._sprite3D2:getMesh():getMeshVertexAttribute(i - 1) + self._state:setVertexAttribPointer(attributeNames[meshattribute.vertexAttrib + 1], + meshattribute.size, + meshattribute.type, + false, + self._sprite3D2:getMesh():getVertexSizeInBytes(), + offset1) + offset1 = offset1 + meshattribute.attribSizeBytes + end + + self._state:setUniformVec4("u_fogColor", cc.vec4(0.5,0.5,0.5,1.0)) + self._state:setUniformFloat("u_fogStart",10) + self._state:setUniformFloat("u_fogEnd",60) + self._state:setUniformInt("u_fogEquation" ,0) + + self._layer3D:addChild(self._sprite3D1) + self._sprite3D1:setPosition3D( cc.vec3( 0, 0,0 ) ) + self._sprite3D1:setScale(2.0) + self._sprite3D1:setRotation3D(cc.vec3(-90,180,0)) + + self._layer3D:addChild(self._sprite3D2) + self._sprite3D2:setPosition3D( cc.vec3( 0, 0,-20 ) ) + self._sprite3D2:setScale(2.0) + self._sprite3D2:setRotation3D(cc.vec3(-90,180,0)) + + if self._camera == nil then + self._camera = cc.Camera:createPerspective(60, s.width/s.height, 1, 1000) + self._camera:setCameraFlag(cc.CameraFlag.USER1) + self._camera:setPosition3D(cc.vec3(0, 30, 40)) + self._camera:lookAt(cc.vec3(0,0,0), cc.vec3(0, 1, 0)) + + self._layer3D:addChild(self._camera) + end + + self._layer3D:setCameraMask(2) + + local targetPlatform = cc.Application:getInstance():getTargetPlatform() + if targetPlatform == cc.PLATFORM_OS_ANDROID or targetPlatform == cc.PLATFORM_OS_WINRT or targetPlatform == cc.PLATFORM_OS_WP8 then + self._backToForegroundListener = cc.EventListenerCustom:create("event_renderer_recreated", function (eventCustom) + -- body + cc.Director:getInstance():setClearColor(cc.c4f(0.5,0.5,0.5,1)) + local glProgram = self._state:getGLProgram() + glProgram:reset() + glProgram:initWithFilenames("Sprite3DTest/fog.vert","Sprite3DTest/fog.frag") + glProgram:link() + glProgram:updateUniforms() + + self._state:setUniformVec4("u_fogColor", cc.vec4(0.5,0.5,0.5,1.0)) + self._state:setUniformFloat("u_fogStart",10) + self._state:setUniformFloat("u_fogEnd",60) + self._state:setUniformInt("u_fogEquation" ,0) + end) + cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(self._backToForegroundListener, -1) + end +end + +function FogTestDemo:onEnter() + cc.Director:getInstance():setClearColor(cc.c4f(0.5,0.5,0.5,1)) + self:setEventListener() + self:createMenu() + self:createLayer3D() +end + +function FogTestDemo:onExit() + cc.Director:getInstance():setClearColor(cc.c4f(0,0,0,1)) + if nil ~= self._camera then + self._camera = nil + end + local targetPlatform = cc.Application:getInstance():getTargetPlatform() + if targetPlatform == cc.PLATFORM_OS_ANDROID or targetPlatform == cc.PLATFORM_OS_WINRT or targetPlatform == cc.PLATFORM_OS_WP8 then + cc.Director:getInstance():getEventDispatcher():removeEventListener(self._backToForegroundListener) + end +end + +function FogTestDemo:title() + return "Fog Test Demo" +end + +function FogTestDemo:subtitle() + return "" +end + +local OperateCamType = +{ + MoveCamera = 0, + RotateCamera = 1, +} + +local CameraArcBallDemo = class("CameraArcBallDemo", function () + local layer = cc.Layer:create() + Helper.initWithLayer(layer) + return layer +end) + +function CameraArcBallDemo:ctor() + -- body + self:init() +end + +function CameraArcBallDemo:init() + self._layer3D = nil + self._cameraType = CameraType.FreeCamera + self._camera = nil + self._drawGrid = nil + self._sprite3D1 = nil + self._sprite3D2 = nil + self._radius = 1.0 + self._distanceZ = 50.0 + self._operate = OperateCamType.RotateCamera + self._center = cc.vec3(0, 0, 0) + self._target = 0 + + Helper.titleLabel:setString(self:title()) + Helper.subtitleLabel:setString(self:subtitle()) + + self:registerScriptHandler(function (event) + if event == "enter" then + self:onEnter() + elseif event == "exit" then + self:onExit() + end + end) +end + +function CameraArcBallDemo:projectToSphere(r, x, y) + local d, t, z + d = math.sqrt(x*x + y*y) + --inside sphere + if d < r * 0.70710678118654752440 then + z = math.sqrt(r*r - d*d) + else--on hyperbola + t = r / 1.41421356237309504880 + z = t*t / d + end + return z +end + +function CameraArcBallDemo:calculateArcBall(axis, angle, p1x, p1y, p2x, p2y) + local rotation_matrix = cc.mat4.createRotation(self._rotationQuat, cc.mat4.createIdentity()) + --rotation y + local uv = mat4_transformVector(rotation_matrix , 0.0, 1.0, 0.0, 0.0, cc.vec3(0.0, 0.0, 0.0)) + --rotation x + local sv = mat4_transformVector(rotation_matrix, 1.0, 0.0, 0.0, 0.0, cc.vec3(0.0, 0.0, 0.0)) + --rotation z + local lv = mat4_transformVector(rotation_matrix, 0.0, 0.0, -1.0, 0.0, cc.vec3(0.0, 0.0, 0.0)) + --start point screen transform to 3d + local projectZ1 = self:projectToSphere(self._radius, p1x, p1y) + local p1 = cc.vec3(sv.x * p1x + uv.x * p1y - lv.x * projectZ1, sv.y * p1x + uv.y * p1y - lv.y * projectZ1 , sv.z * p1x + uv.z * p1y - lv.z * projectZ1) + --end point screen transform to 3d + local projectZ2 = self:projectToSphere(self._radius, p2x, p2y) + local p2 = cc.vec3(sv.x * p2x + uv.x * p2y - lv.x * projectZ2, sv.y * p2x + uv.y * p2y - lv.y * projectZ2 , sv.z * p2x + uv.z * p2y - lv.z * projectZ2) + --calculate rotation axis + axis = vec3_cross(p2, p1, axis) + axis = cc.vec3normalize(axis) + + local t = math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y) + (p2.z - p1.z) * (p2.z - p1.z)) / (2.0 * self._radius) + --clamp -1 to 1 + if t > 1.0 then + t = 1.0 + end + + if t < -1.0 then + t = -1.0 + end + --rotation angle + angle = math.asin(t) + + return axis, angle +end +function CameraArcBallDemo:setEventListener() + local listener = cc.EventListenerTouchAllAtOnce:create() + + listener:registerScriptHandler(function(touchs, event) + if #touchs ~= 0 then + if self._operate == OperateCamType.RotateCamera then + local visibleSize = cc.Director:getInstance():getVisibleSize() + local prelocation = touchs[1]:getPreviousLocationInView() + local location = touchs[1]:getLocationInView() + location.x = 2.0 * (location.x) / (visibleSize.width) - 1.0 + location.y = 2.0 * (visibleSize.height - location.y) / (visibleSize.height) - 1.0 + prelocation.x = 2.0 * (prelocation.x) / (visibleSize.width) - 1.0 + prelocation.y = 2.0 * (visibleSize.height - prelocation.y) / (visibleSize.height) - 1.0 + + local axes = cc.vec3(0,0,0) + local angle = 0.0 + --calculate rotation quaternion parameters + axes , angle = self:calculateArcBall(axes, angle, prelocation.x, prelocation.y, location.x, location.y) + + --get rotation quaternion + local halfAngle = angle * 0.5 + local sinHalfAngle = math.sin(math.deg(halfAngle)) + + local normal = axes + normal = cc.vec3normalize(normal) + local quat = cc.quaternion(normal.x * sinHalfAngle, normal.y * sinHalfAngle, normal.z * sinHalfAngle, math.cos(math.deg(halfAngle))) + local x = quat.w * self._rotationQuat.x + quat.x * self._rotationQuat.w + quat.y * self._rotationQuat.z - quat.z * self._rotationQuat.y + local y = quat.w * self._rotationQuat.y - quat.x * self._rotationQuat.z + quat.y * self._rotationQuat.w + quat.z * self._rotationQuat.x + local z = quat.w * self._rotationQuat.z + quat.x * self._rotationQuat.y - quat.y * self._rotationQuat.x + quat.z * self._rotationQuat.w + local w = quat.w * self._rotationQuat.w - quat.x * self._rotationQuat.x - quat.y * self._rotationQuat.y - quat.z * self._rotationQuat.z + self._rotationQuat = cc.quaternion(x, y, z, w) + + self:updateCameraTransform() + + elseif self._operate == OperateCamType.MoveCamera then + local previousLocation = touchs[1]:getPreviousLocation() + local location = touchs[1]:getLocation() + local newPos = cc.p(previousLocation.x - location.x, previousLocation.y - location.y) + self._distanceZ = self._distanceZ - newPos.y * 0.1 + + self:updateCameraTransform() + end + end + end, cc.Handler.EVENT_TOUCHES_MOVED) + + local eventDispatcher = self:getEventDispatcher() + eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self) +end + +function CameraArcBallDemo:createLayer3D() + local s = cc.Director:getInstance():getWinSize() + + cc.MenuItemFont:setFontName("fonts/arial.ttf") + cc.MenuItemFont:setFontSize(20) + + local menuItem1 = cc.MenuItemFont:create("Switch Operation") + menuItem1:setColor(cc.c3b(0,200,20)) + menuItem1:registerScriptTapHandler(function (tag, sender ) + if self._operate == OperateCamType.MoveCamera then + self._operate = OperateCamType.RotateCamera + elseif self._operate == OperateCamType.RotateCamera then + self._operate = OperateCamType.MoveCamera + end + end) + local menuItem2 = cc.MenuItemFont:create("Switch Target") + menuItem2:setColor(cc.c3b(0,200,20)) + menuItem2:registerScriptTapHandler(function (tag, sender ) + if self._target == 0 then + self._target = 1 + self._center = self._sprite3D2:getPosition3D() + self:updateCameraTransform() + elseif self._target == 1 then + self._target = 0 + self._center = self._sprite3D1:getPosition3D() + self:updateCameraTransform() + end + end) + local menu = cc.Menu:create(menuItem1,menuItem2) + menu:setPosition(cc.p(0.0, 0.0)) + menuItem1:setPosition(VisibleRect:left().x + 80, VisibleRect:top().y -70) + menuItem2:setPosition(VisibleRect:left().x + 80, VisibleRect:top().y -100) + self:addChild(menu, 1) + + local layer3D = cc.Layer:create() + self:addChild(layer3D,0) + self._layer3D = layer3D + + if self._camera == nil then + self._camera = cc.Camera:createPerspective(60, s.width/s.height, 1, 1000) + self._camera:setCameraFlag(cc.CameraFlag.USER1) + self._camera:setPosition3D(cc.vec3(0, 10, 50)) + self._camera:lookAt(cc.vec3(0, 0, 0), cc.vec3(0, 1, 0)) + self._layer3D:addChild(self._camera) + end + + self._sprite3D1 = cc.Sprite3D:create("Sprite3DTest/orc.c3b") + self._sprite3D1:setScale(0.5) + self._sprite3D1:setRotation3D(cc.vec3(0,180,0)) + self._sprite3D1:setPosition3D(cc.vec3(0,0,0)) + self._layer3D:addChild(self._sprite3D1) + + self._sprite3D2 = cc.Sprite3D:create("Sprite3DTest/boss.c3b") + self._sprite3D2:setScale(0.6) + self._sprite3D2:setRotation3D(cc.vec3(-90,0,0)) + self._sprite3D2:setPosition3D(cc.vec3(20,0,0)) + self._layer3D:addChild(self._sprite3D2) + + self._drawGrid = cc.DrawNode3D:create() + --draw x + for j = -20, 20 do + self._drawGrid:drawLine(cc.vec3(-100, 0, 5*j), cc.vec3(100, 0, 5*j),cc.c4f(1, 0, 0, 1)) + end + + --draw z + for j = -20, 20 do + self._drawGrid:drawLine(cc.vec3(5*j, 0, -100), cc.vec3(5*j, 0, 100),cc.c4f(0,0,1,1)) + end + + --draw y + self._drawGrid:drawLine(cc.vec3(0, 0, 0), cc.vec3(0,50,0), cc.c4f(0,1,0,1)) + + self._layer3D:addChild(self._drawGrid) + + self._layer3D:setCameraMask(2) + self:updateCameraTransform() +end + +function CameraArcBallDemo:updateCameraTransform() + -- body + local trans = cc.mat4.createTranslation(cc.vec3(0.0, 10.0, self._distanceZ), cc.mat4.createIdentity()) + local rot = cc.mat4.createRotation(self._rotationQuat, cc.mat4.createIdentity()) + local center = cc.mat4.createTranslation(self._center, cc.mat4.createIdentity()) + local result = mat4_multiply(mat4_multiply(trans, rot), center) + + self._camera:setNodeToParentTransform(result) +end + +function CameraArcBallDemo:onEnter() + self._rotationQuat = cc.quaternion(0.0, 0.0, 0.0, 1.0) + self:setEventListener() + self:createLayer3D() +end + +function CameraArcBallDemo:onExit() + if self._camera ~= nil then + self._camera = nil + end +end + +function CameraArcBallDemo:title() + return "Camera ArcBall Moving" +end + +function CameraArcBallDemo:subtitle() + return "" +end + function Camera3DTestMain() cclog("Camera3DTestMain") local scene = cc.Scene:create() - scene:addChild(Camera3DTestDemo.new()) + + Helper.createFunctionTable = + { + Camera3DTestDemo.create, + CameraRotationTest.create, + FogTestDemo.create, + CameraArcBallDemo.create, + } + scene:addChild(Helper.createFunctionTable[1]()) scene:addChild(CreateBackMenuItem()) diff --git a/tools/tolua/cocos2dx_3d.ini b/tools/tolua/cocos2dx_3d.ini index 13f9095598..d554da2066 100644 --- a/tools/tolua/cocos2dx_3d.ini +++ b/tools/tolua/cocos2dx_3d.ini @@ -35,7 +35,7 @@ classes = Animate3D Sprite3D Animation3D Skeleton3D ^Mesh$ AttachNode BillBoard # will apply to all class names. This is a convenience wildcard to be able to skip similar named # functions from all classes. -skip = Mesh::[create getAABB getVertexBuffer hasVertexAttrib getMeshVertexAttribCount getMeshVertexAttribute getVertexSizeInBytes getSkin getMeshIndexData getGLProgramState getPrimitiveType getIndexCount getIndexFormat getIndexBuffer], +skip = Mesh::[create getAABB getVertexBuffer hasVertexAttrib getSkin getMeshIndexData getGLProgramState getPrimitiveType getIndexCount getIndexFormat getIndexBuffer], Sprite3D::[getSkin getAABB getMeshArrayByName], Skeleton3D::[create], Animation3D::[getBoneCurveByName],