1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # Base entities of the depth 3D game framework
18 intrude import gamnit
::flat
20 # Visible entity in the game world, represented by its `model` modified by the other attributes
23 # Model used to dray this actor
26 # Position of this sprite in world coordinates
27 var center
: Point3d[Float] is writable
29 # Rotation on the Z axis
30 var rotation
= 0.0 is writable
32 # Scale applied to this sprite
33 var scale
= 1.0 is writable
35 # Transparency applied to the texture on draw
36 var alpha
= 1.0 is writable
39 # Entire 3D model defined by its `leaves`, an association of `Mesh` to `Material`
42 # Load this model in memory
45 # All `LeafModel` composing this model
47 # Usually, there is one `LeafModel` per material.
48 # At each frame, each material is asked to draw all the live `LeafModel` instaces.
49 fun leaves
: Array[LeafModel] is abstract
52 # Model composed of one or many other `LeafModel`
56 redef var leaves
= new Array[LeafModel]
59 # Single model with a `mesh` and `material`
61 # Only leaves are actually drawn by the `material`.
65 # Mesh forming this model
68 # Material applied on this model
69 var material
: Material
71 redef var leaves
= [self]
74 # Material for a model or how to draw the model
75 abstract class Material
79 # This method should be refined by subclasses as the default implementation is a no-op.
81 # This method is called on many materials for many `actor` and `model` at each frame.
82 # It is expected to use a `GLProgram` and call an equivalent to `glDrawArrays`.
83 # However, it should not call `glClear` nor `GamnitDisplay::flip`.
84 fun draw
(actor
: Actor, model
: LeafModel) do end
87 # Mesh with all geometry data
90 # Vertices coordinates
91 var vertices
= new Array[Float] is lazy
, writable
93 # Indices to draw triangles with `glDrawElements`
95 # If `not_empty`, use `glDrawElements`, otherwise use `glDrawArrays`.
96 var indices
= new Array[Int] is lazy
, writable
98 private var indices_c
= new CUInt16Array.from
(indices
) is lazy
, writable
100 # Normals on each vertex
101 var normals
= new Array[Float] is lazy
, writable
103 # Coordinates on the texture per vertex
104 var texture_coords
= new Array[Float] is lazy
, writable
106 # `GLDrawMode` used to display this mesh, defaults to `gl_TRIANGLES`
107 fun draw_mode
: GLDrawMode do return gl_TRIANGLES
109 # Create an UV sphere of `radius` with `n_meridians` and `n_parallels`
110 init uv_sphere
(radius
: Float, n_meridians
, n_parallels
: Int)
115 var vertices
= new Array[Float].with_capacity
(w
*h
*3)
116 self.vertices
= vertices
118 var texture_coords
= new Array[Float].with_capacity
(w
*h
*2)
119 self.texture_coords
= texture_coords
121 var normals
= new Array[Float].with_capacity
(w
*h
*3)
122 self.normals
= normals
127 var u
= m
.to_f
* 2.0 * pi
/ (w-1
).to_f
128 var v
= p
.to_f
* pi
/ (h-1
).to_f
130 vertices
.add radius
* u
.cos
* v
.sin
131 vertices
.add radius
* v
.cos
132 vertices
.add radius
* u
.sin
* v
.sin
134 texture_coords
.add
(1.0 - m
.to_f
/(w-1
).to_f
)
135 texture_coords
.add
(p
.to_f
/(h-1
).to_f
)
137 normals
.add u
.cos
* v
.sin
139 normals
.add u
.sin
* v
.sin
144 var indices
= new Array[Int].with_capacity
((w-1
)*(h-1
)*6)
145 self.indices
= indices
161 # Dimensions of this geometry using the min and max of all points on each axis
162 var dimensions
: Point3d[Float] is lazy
, writable do
163 assert vertices
.length
% 3 == 0
173 while i
< vertices
.length
do
190 return new Point3d[Float](maxx-minx
, maxy-miny
, maxz-minz
)
193 # Center of the geometry
194 var center
: Point3d[Float] is lazy
, writable do
195 assert vertices
.length
% 3 == 0
205 while i
< vertices
.length
do
222 var center
= new Point3d[Float](
232 # Instances of this class define a light source position and type.
235 # TODO point light, spotlight, directional light, etc.
237 # Center of this light source in world coordinates
238 var position
= new Point3d[Float](0.0, 1000.0, 0.0)
243 # Live actors to be drawn on screen
244 var actors
= new Array[Actor]
246 # Single light of the scene
247 var light
= new Light
249 # TODO move `actors & light` to a scene object
250 # TODO support more than 1 light