Fancy3D引擎sample学习(C)

1、cameraControl

摄像机模板MouseLeft实现摄像机的平移,MouseLeft+Alt实现摄像机的旋转。

首先,引擎中的坐标系是左手坐标系。我在第一挂限的“空中”悬着一个点P。你站在O点看这个点P。

首先,要从x轴正方向,沿逆时针旋转到点P的垂直投影线上,这就是方位角phi;然后再往高出寻找它,又得到了一个仰角,这就是倾斜角theta。

_rd.camera:movePhi(弧度)和_rd.camera:moveTheta(弧度)就是移动这两个参数。

摄像机可以看做是一个四棱锥,锥顶是eye,有一个近截面viewNear(eye到该截面的距离是_rd.camera.viewNear)和远截面viewFar,我们能看到的图像是在近截面和远截面之间的区域,该区域内有一个参数是look。映射到屏幕的话,就是人是eye,屏幕是可见区域,内部有look位置。

到近截面的距离/(eye-look的距离) = 屏幕上移动的距离/look移动的距离(eye移动的距离)

 1 mouse = {mousex = 0, mousey = 0}
 2 _app:onMouseMove(function(x, y)
 3     print(x, y)
 4     if _sys:isKeyDown(_System.MouseLeft) then
 5         if _sys:isKeyDown(_System.KeyAlt) then
 6             _rd.camera:movePhi(-(mouse.mousex - x) * 0.005)
 7             _rd.camera:moveTheta(-(mouse.mousey - y) * 0.005)
 8         else
 9             local dir = _Vector3.sub(_rd.camera.look, _rd.camera.eye)    --_Vector.sub(v1, v2)  v1-v2
10             local vx = _Vector3.cross(dir, _rd.camera.up):normalize()
11             local vy = _Vector3.cross(vx, dir):normalize()
12             local nearx = _Vector3.mul(vx, -(mouse.mousex - x) * 0.001)
13             local neary = _Vector3.mul(vy, -(mouse.mousey - y) * 0.001)
14             local movex = _Vector3.mul(nearx, dir:magnitude() / _rd.camera.viewNear)
15             local movey = _Vector3.mul(neary, dir:magnitude() / _rd.camera.viewNear)
16             local move = _Vector3.add(movex , movey)
17             _rd.camera:moveEye(_rd.camera.eye.x + move.x, _rd.camera.eye.y + move.y, _rd.camera.eye.z + move.z)
18             _rd.camera:moveLook(_rd.camera.look.x + move.x, _rd.camera.look.y + move.y, _rd.camera.look.z + move.z)
19         end
20     end
21     mouse.mousex = x
22     mouse.mousey = y
23 end)
24 
25 _app:onMouseWheel(function(delta)
26     local dir = _Vector3.sub(_rd.camera.look, _rd.camera.eye)
27     dir = _Vector3.mul(dir, 1 - 0.05 * delta)
28     _rd.camera.eye = _Vector3.sub(_rd.camera.look, dir)
29     --_rd.camera:moveRadius(delta*3)  可以用一条语句替换
30 end)
31 
32 _app:onIdle(function(e) 
33     _rd:drawAxis(50)
34 end)
View Code

 2、Client-Global

_utcDate(number):写number(单位:毫秒)的话,返回从1970.1.1+number的UTC时间,属性包括year、month、day。

_localDate(number)同上,只不过是返回本地时间。

_random(a, b)返回a~b之间的随机数(小数)

_dofile('file') 类似于#define

_dostring('code') 执行code代码

_info() 输出作用

_abort 终止程序

3、clipper

创建一个plane和teapot,plane作为裁截面。用键盘事件控制截面的移动。

clipper = _Clipper.new():clipZNegtive(0) 创建一个截面是看不到的,这个程序把plane的矩阵变化和clipper的平移进行同步,所以才实现了可视化的截面效果。

 1 _dofile('cameracontrol.lua')
 2 
 3 clipz = 0
 4 pos = 1
 5 
 6 teapot, plane = _mf:createTeapot(), _mf:createPlane()
 7 plane.transform:setScaling(50, 50, 50)
 8 teapot.transform:setScaling(5, 5, 5)
 9 
10 _rd.camera.eye = _Vector3.new(25, 25, 25)
11 _rd:useLight(_AmbientLight.new())
12 _rd:useLight(_SkyLight.new())
13 mat = _Matrix3D.new()
14 
15 clipper = _Clipper.new():clipZNegative(0)
16 
17 font = _Font.new('Arial', 10)
18 font.textColor = _Color.Yellow
19 
20 function newclipper()
21     mat:setTranslation(0, 0, clipz)
22     if pos == 0 then
23         clipper:clipZPositive(clipz)
24     else
25         clipper:clipZNegative(clipz)
26     end
27 end
28 
29 _app:onKeyDown(function(key)
30     if key == _System.KeyW then
31         if clipz < 4 then
32             clipz = clipz + 1
33             newclipper()
34         end
35     elseif key == _System.KeyS then
36         if clipz > -5 then
37             clipz = clipz - 1
38             newclipper()
39         end
40     elseif key == _System.Key1 then
41         if pos == 0 then
42             pos = 1
43         elseif pos == 1 then
44             pos = 0
45         end
46         newclipper()
47     end
48 end)
49 
50 _app:onIdle(function(e)
51     font:drawText(0, 0, 'Press 1 to Switch Positive or Negative')
52     font:drawText(0, 14, 'Press w to up')
53     font:drawText(0, 28, 'Press s to down')
54 
55     _rd.wireframe = true
56     _rd:pushMatrix3D(mat)
57         plane:drawMesh()
58     _rd:popMatrix3D()
59     _rd.wireframe = false
60 
61     _rd:useClipper(clipper)
62         teapot:drawMesh()
63     _rd:popClipper()
64 end)
View Code

 4、clipper-fadez

clipper:fadez(z1, z2, clicolor) z1开始渐入的平面,z2完全渐入的平面,clicolor渐入的颜色。

 1 _dofile('cameracontrol.lua')
 2 _rd.camera.eye = _Vector3.new(30, 30, 30)
 3 _rd:useLight(_AmbientLight.new())
 4 _rd:useLight(_SkyLight.new())
 5 
 6 teapot = _mf:createTeapot()
 7 teapot.transform:setScaling(10, 10, 10)
 8 
 9 clicolor = _Color.DarkBlue
10 clipper = _Clipper.new():fadeZ(0, 8, clicolor)
11 --_rd.bgColor = clicolor
12 
13 font = _Font.new('Arial', 10)
14 font.textColor = _Color.Yellow
15 
16 z1 = -4
17 z2 = 5
18 
19 _app:onKeyDown(function(key)
20     if key == _System.KeyW then
21         if z1 < 10 then
22             z1 = z1 + 2
23             clipper:fadeZ(z1, z2, clicolor)
24         end
25     elseif key == _System.KeyS then
26         if z1 > -10 then
27             z1 = z1 - 2
28             clipper:fadeZ(z1, z2, clicolor)
29         end
30     elseif key == _System.KeyE then
31         if z2 < 9 then
32             z2 = z2 + 2
33             clipper:fadeZ(z1, z2, clicolor)
34         end
35     elseif key == _System.KeyD then
36         if z2 > -9 then
37             z2 = z2 - 2
38             clipper:fadeZ(z1, z2, clicolor)
39         end
40     end
41     print(z1, z2)
42 end)
43 
44 _app:onIdle(function(e)
45     font:drawText(0, 0, 'Press WS to adjust fade begin')
46     font:drawText(0, 14, 'Press ED to adjust fade end')
47     _rd:drawAxis(30)
48     _rd:useClipper(clipper)
49         teapot:drawMesh()
50     _rd:popClipper()
51 end)
View Code

 5、collision-sphereVsSegment

检测线段和球体碰撞,相交的话线段变成红色

_rd:pickXYPlane(x, y, p, v1)  从屏幕上点(x, y) pick 平面z = p的结果,返回向量保存在v1

_con:sphereVsSegment(c , r, v1, v2)

球心坐标c,半径r,线段v1v2 返回bool值

 1 _dofile('cameracontrol.lua')
 2 
 3 plane = _mf:createPlane()
 4 sphere = _mf:createSphere()
 5 _mf:paintDiffuse(plane, _Color.Gray)
 6 
 7 c = _Vector3.new(0, 50, 0)
 8 v1 = _Vector3.new(0, 0, 0)
 9 v2 = _Vector3.new(0, 0, 0)
10 
11 mat1 = _Matrix3D.new():setScaling(200, 200, 200):mulTranslationRight(0, 0, -1)
12 mat2 = _Matrix3D.new():setScaling(10, 10, 10):mulTranslationRight(c)
13 
14 _app:onMouseDown(function(btn, x, y)
15     if btn == _System.MouseLeft then
16         v1 = _rd:pickXYPlane(x, y, 0, v1)
17     elseif btn == _System.MouseRight then
18         v2 = _rd:pickXYPlane(x, y, 0, v2)
19     end
20 end)
21 
22 _app:onIdle(function(e)
23     _rd:pushMatrix3D(mat1)
24         plane:drawMesh()
25     _rd:popMatrix3D()
26     _rd:pushMatrix3D(mat2)
27         sphere:drawMesh()
28     _rd:popMatrix3D()
29 
30     local color = _Color.Green
31     if _con:sphereVsSegment(c, 10, v1, v2) then
32         color = _Color.Red
33     end
34 
35     _rd:draw3DLine(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, color)
36 end)
View Code

 6、color

_rd:drawLine(x1,y1,x2,y2,color) 从(x1,y1)到(x2,y2)颜色是color的线段

 1 _info( "_Color.Red=" .. _Color.Red .. "      ,_Color.Purple=" .. _Color.Purple );
 2 
 3 _info( "mul red and Purple = " .. _Color.mul( _Color.Red,_Color.Purple));
 4 
 5 _info( "add red and Purple = " .. _Color.add( _Color.Red,_Color.Purple));
 6 
 7 _info( "lerp red and Purple = " .. _Color.lerp( _Color.Red,_Color.Purple,0.6));
 8 
 9 function render( e )
10     _rd:drawLine(0,100,1000,100,_Color.Red )
11     _rd:drawLine(0,200,1000,200,_Color.Purple)
12     _rd:drawLine(0,300,1000,300,_Color.mul( _Color.Red,_Color.Purple))
13     _rd:drawLine(0,400,1000,400,_Color.add( _Color.Red,_Color.Purple))
14     _rd:drawLine(0,500,1000,500,_Color.lerp( _Color.Red,_Color.Purple,0.5))
15 end
16 
17 _app:onIdle( render )
View Code

 

posted @ 2013-11-22 15:24  丿聪丶  阅读(685)  评论(0)    收藏  举报