camera.monkey2 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. Namespace mojo3d
  2. #rem monkeydoc The Camera class.
  3. #end
  4. Class Camera Extends Entity
  5. #rem monkeydoc Creates a new camera.
  6. #end
  7. Method New( parent:Entity=Null )
  8. Super.New( parent )
  9. Name="Camera"
  10. Viewport=New Recti( 0,0,640,480 )
  11. Near=.1
  12. Far=100
  13. FOV=90
  14. AddInstance()
  15. Visible=True
  16. End
  17. Method New( view:View,parent:Entity=Null )
  18. Super.New( parent )
  19. Name="Camera"
  20. View=view
  21. Near=.1
  22. Far=100
  23. FOV=90
  24. AddInstance()
  25. Visible=True
  26. End
  27. #rem monkeydoc Copies the camera.
  28. #end
  29. Method Copy:Camera( parent:Entity=Null ) Override
  30. Local copy:=OnCopy( parent )
  31. CopyTo( copy )
  32. Return copy
  33. End
  34. #rem monkeydoc View camera is tracking.
  35. #end
  36. Property View:View()
  37. Return _view
  38. Setter( view:View )
  39. _view=view
  40. If _view SetViewport( _view.Rect )
  41. End
  42. #rem monkeydoc Viewport.
  43. If [[View]] is non-null, this property will automatically track the view's rect.
  44. This property can only be modified if View is null.
  45. #end
  46. Property Viewport:Recti()
  47. Return _viewport
  48. Setter( viewport:Recti )
  49. Assert( Not _view,"Viewport cannot be manually modified for a camera with a view" )
  50. SetViewport( viewport )
  51. End
  52. #rem monkeydoc Aspect ratio.
  53. Defaults to 1.0.
  54. #end
  55. Property Aspect:Float()
  56. Return _aspect
  57. End
  58. #rem monkeydoc Vertical field of view in degrees.
  59. Defaults to 90.0.
  60. #end
  61. [jsonify=1]
  62. Property FOV:Float()
  63. Return _fov
  64. Setter( fov:Float )
  65. _fov=fov
  66. _dirty|=Dirty.ProjMatrix
  67. End
  68. #rem monkeydoc Near clip plane distance.
  69. Defaults to 0.1 (10 cenitimetres).
  70. The ratio of Far/Near clip planes should be kept as low as possible to reduce numerical precision errors.
  71. #end
  72. [jsonify=1]
  73. Property Near:Float()
  74. Return _near
  75. Setter( near:Float )
  76. _near=near
  77. _dirty|=Dirty.ProjMatrix
  78. End
  79. #rem monkeydoc Far clip plane distance.
  80. Defaults to 100.0 (100 metres).
  81. The ratio of Far/Near clip planes should be kept as low as possible to reduce numerical precision errors.
  82. #end
  83. [jsonify=1]
  84. Property Far:Float()
  85. Return _far
  86. Setter( far:Float )
  87. _far=far
  88. _dirty|=Dirty.ProjMatrix
  89. End
  90. #rem monkeydoc The projection matrix.
  91. #end
  92. Property ProjectionMatrix:Mat4f()
  93. If _dirty & Dirty.ProjMatrix
  94. _projMatrix=Mat4f.Perspective( _fov,_aspect,_near,_far )
  95. _dirty&=~Dirty.ProjMatrix
  96. Endif
  97. Return _projMatrix
  98. Setter( matrix:Mat4f )
  99. _projMatrix=matrix
  100. _dirty&=~Dirty.ProjMatrix
  101. End
  102. #rem monkeydoc Renders the camera to a canvas.
  103. #end
  104. Method Render( canvas:Canvas )
  105. If _view SetViewport( _view.Rect )
  106. Local gdevice:=canvas.GraphicsDevice
  107. Local rviewport:=canvas.RenderMatrix * Self.Viewport
  108. Renderer.GetCurrent().Render( gdevice.RenderTarget,gdevice.RenderTargetSize,rviewport,Scene,InverseMatrix,ProjectionMatrix,Near,Far )
  109. End
  110. #rem monkeydoc Converts a point from world coordinates to viewport coordinates.
  111. #end
  112. Method ProjectToViewport:Vec2f( worldVertex:Vec3f )
  113. Local clip_coords:=ProjectionMatrix * InverseMatrix * New Vec4f( worldVertex,1.0 )
  114. Local ndc_coords:=clip_coords.XY/clip_coords.w
  115. Local vp_coords:=Cast<Vec2f>( Viewport.Size ) * (ndc_coords * 0.5 + 0.5)
  116. vp_coords.y=Viewport.Height-vp_coords.y-1
  117. Return vp_coords
  118. End
  119. #rem monkeydoc Converts a point from viewport coordinates to world coordinates.
  120. #end
  121. Method UnprojectFromViewport:Vec3f( viewportCoords:Vec2f )
  122. viewportCoords.y=Viewport.Height-viewportCoords.y-1
  123. Local vp_coords:=viewportCoords / Cast<Vec2f>( Viewport.Size ) * 2.0 - 1.0
  124. Local clip_coords:=New Mat4f( Matrix ) * -ProjectionMatrix * New Vec4f( vp_coords,-1.0,1.0 )
  125. Local world_coords:=clip_coords.XYZ/clip_coords.w
  126. Return world_coords
  127. End
  128. Method Pick:RayCastResult( viewportCoords:Vec2f,collisionMask:Int=-1 )
  129. If viewportCoords.x<0 Or viewportCoords.y<0 Or viewportCoords.x>=_viewport.Width Or viewportCoords.y>=_viewport.Height Return Null
  130. Local vpcoords:=viewportCoords
  131. vpcoords.x=vpcoords.x/_viewport.Width*2-1
  132. vpcoords.y=vpcoords.y/_viewport.Height*2-1
  133. Local iproj:=-ProjectionMatrix
  134. Local rayFrom:=Matrix * (iproj * New Vec3f( vpcoords,-1 ))
  135. Local rayTo:=Matrix * (iproj * New Vec3f( vpcoords,1 ))
  136. Return Scene.RayCast( rayFrom,rayTo,collisionMask )
  137. End
  138. Method MousePick:RayCastResult( collisionMask:Int=-1 )
  139. Local mouse:=Cast<Vec2f>( Mouse.Location )
  140. If App.ActiveWindow mouse.y=App.ActiveWindow.Height-mouse.y
  141. If _view mouse=_view.TransformWindowPointToView( mouse )
  142. mouse.x-=Viewport.min.x
  143. mouse.y-=Viewport.min.y
  144. Return Pick( mouse,collisionMask )
  145. End
  146. Protected
  147. Method New( camera:Camera,parent:Entity )
  148. Super.New( camera,parent )
  149. Viewport=camera.Viewport
  150. Near=camera.Near
  151. Far=camera.Far
  152. FOV=camera.FOV
  153. AddInstance( camera )
  154. End
  155. Method OnCopy:Camera( parent:Entity ) Override
  156. Return New Camera( Self,parent )
  157. End
  158. Method OnShow() Override
  159. Scene.Cameras.Add( Self )
  160. End
  161. Method OnHide() Override
  162. Scene.Cameras.Remove( Self )
  163. End
  164. Private
  165. Enum Dirty
  166. ProjMatrix=1
  167. End
  168. Field _view:View
  169. Field _viewport:Recti
  170. Field _aspect:Float
  171. Field _fov:Float
  172. Field _near:Float
  173. Field _far:Float
  174. Field _projMatrix:Mat4f
  175. Field _dirty:Dirty=Dirty.ProjMatrix
  176. Method SetViewport( viewport:Recti )
  177. If viewport=_viewport Return
  178. _viewport=viewport
  179. _aspect=Float( _viewport.Width )/Float( _viewport.Height )
  180. _dirty|=Dirty.ProjMatrix
  181. End
  182. End