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)
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)
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)
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)
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 )

浙公网安备 33010602011771号