Merge pull request #10247 from samuele3hu/v3_4_fi

Add more 3D test case and adjust some binding function
This commit is contained in:
minggo 2015-01-28 13:41:34 +08:00
commit f54916cf69
4 changed files with 928 additions and 31 deletions

View File

@ -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");
vec3_to_luaval(tolua_S, translation);
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;

View File

@ -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,66 @@ end
function cc.mat4.transformVector(self, vector, dst)
return mat4_transformVector(self, vector, dst)
end
function cc.mat4.multiply(self, mat)
return mat4_multiply(self, mat)
end
function cc.mat4.decompose(self, scale, rotation, translation)
return mat4_decompose(self, scale ,rotation, translation)
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

View File

@ -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()
@ -442,6 +444,9 @@ function Camera3DTestDemo:onExit()
end
function Camera3DTestDemo:init()
Helper.titleLabel:setString(self:title())
Helper.subtitleLabel:setString(self:subtitle())
self:registerScriptHandler(function (event)
if event == "enter" then
self:onEnter()
@ -451,10 +456,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 = cc.mat4.new(camNode:getNodeToWorldTransform()):decompose(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 = cc.mat4.new(center:multiply(rot)):multiply(trans)
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())

View File

@ -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],