manual: CI check with nitunit
[nit.git] / lib / gamnit / depth / more_lights.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # More implementations of `Light`
16 module more_lights
17
18 import depth_core
19 intrude import cameras_cache
20
21 # TODO
22 #class PointLight
23 #class Spotlight
24
25 # Sun-like light projecting parallel rays
26 class ParallelLight
27 super LightCastingShadows
28
29 # Angle to the light source, around the X axis
30 var pitch = 0.0 is writable
31
32 # Angle to the light source, around the Y axis
33 var yaw = 0.0 is writable
34
35 # Depth texture width, in world coordinates
36 var width = 100.0 is writable
37
38 # Depth texture height, in world coordinates
39 var height = 100.0 is writable
40
41 # Viewport depth, centered on `app.world_camera`
42 var depth = 500.0 is writable
43
44 redef var camera = new ParallelLightCamera(app.display.as(not null), self) is lazy
45 end
46
47 private class ParallelLightCamera
48 super Camera
49
50 var light: ParallelLight
51
52 # Rotation matrix produced by the current rotation of the camera
53 fun rotation_matrix: Matrix
54 do
55 var view = new Matrix.identity(4)
56 view.rotate(light.yaw, 0.0, 1.0, 0.0)
57 view.rotate(light.pitch, 1.0, 0.0, 0.0)
58 return view
59 end
60
61 private fun create_mvp_matrix: Matrix
62 do
63 var near = -light.depth/2.0
64 var far = light.depth/2.0
65
66 var view = new Matrix.identity(4)
67 view.translate(-position.x, -position.y, -position.z)
68 view = view * rotation_matrix
69 var projection = new Matrix.orthogonal(-light.width/2.0, light.width/2.0,
70 -light.height/2.0, light.height/2.0,
71 near, far)
72 return view * projection
73 end
74
75 redef fun mvp_matrix
76 do
77 var m = mvp_matrix_cache
78 if m == null or check_position_changed then
79 m = create_mvp_matrix
80 mvp_matrix_cache = m
81 end
82 return m
83 end
84
85 private var pitch_cache = 0.0
86 private var yaw_cache = 0.0
87 private var width_cache = 0.0
88 private var height_cache = 0.0
89 private var depth_cache = 0.0
90
91 redef fun check_position_changed
92 do
93 if super then return true
94
95 if light.pitch != pitch_cache or
96 light.yaw != yaw_cache or
97 light.width != width_cache or
98 light.height != height_cache or
99 light.depth != depth_cache then
100 pitch_cache = light.pitch
101 yaw_cache = light.yaw
102 width_cache = light.width
103 height_cache = light.height
104 depth_cache = light.depth
105 return true
106 end
107
108 return false
109 end
110 end