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 import gamnit
::flat_core
20 # Visible 3D entity in the game world
22 # Similar to `gamnit::Sprite` which is in 2D.
24 # Each actor associates a `model` to the position `center`.
25 # The appearance is modified by `rotation`, `scale` and `alpha`,
26 # as well as the attributes of `model` itself.
29 # import gamnit::depth
31 # # Load model from the assets folder
32 # var model = new Model("path/in/assets.obj")
34 # # Create and configure an actor
35 # var actor = new Actor(model, new Point3d[Float](0.0, 0.0, 0.0))
38 # # Add to the visible game world
39 # app.actors.add actor
43 # Model used to draw this actor
46 # Position of this sprite in world coordinates
47 var center
: Point3d[Float] is writable
49 # Rotation around the X axis (+ looks up, - looks down)
51 # Positive values look up, and negative look down.
53 # All actor rotations follow the right hand rule.
54 # The default orientation of the model should look towards -Z.
55 var pitch
= 0.0 is writable
57 # Rotation around the Y axis (+ turns left, - turns right)
59 # Positive values turn `self` to the left, and negative values to the right.
61 # All actor rotations follow the right hand rule.
62 # The default orientation of the model should look towards -Z.
63 var yaw
= 0.0 is writable
65 # Rotation around the Z axis (looking to -Z: + turns counterclockwise, - clockwise)
67 # From the default camera point of view, looking down on the Z axis,
68 # positive values turn `self` counterclockwise, and negative values clockwise.
70 # All actor rotations follow the right hand rule.
71 # The default orientation of the model should look towards -Z.
72 var roll
= 0.0 is writable
74 # Scale applied to the model
75 var scale
= 1.0 is writable
77 # Transparency applied to the model on draw
79 # This value may be ignored by some materials.
80 # Non-opaque values may result in artifacts as there is no specialized
81 # support for transparent models and the depth buffer.
82 var alpha
= 1.0 is writable
85 # 3D model composed of `Mesh` and `Material`, loaded from the assets folder by default
87 # Instances can be created at any time and must be loaded after or at the end of `on_create`.
88 # If loading fails, the model is replaced by `placeholder_model`.
91 # import gamnit::depth
93 # var model = new Model("path/in/assets.obj")
97 # The most simple model is `LeafModel`, composed of a single `Mesh` and `Material`.
98 # It can be easily created programmatically to display simple geometries.
99 # Whereas `CompositeModel` is composed of one or many `LeafModel` and is usually
100 # loaded from the assets folder as a `ModelAsset`.
101 # Instances of `ModelAsset` must be in the format OBJ and MAT,
102 # and their texture in PNG or JPG.
105 # Load this model in memory
108 # Errors raised at loading
109 var errors
= new Array[Error]
111 # All `LeafModel` composing this model
113 # Usually, there is one `LeafModel` per material.
114 # At each frame, each material is asked to draw all the live `LeafModel` instaces.
115 fun leaves
: Array[LeafModel] is abstract
118 # Model composed of one or many other `LeafModel`
122 redef var leaves
= new Array[LeafModel]
125 # Basic model with a single `mesh` and `material`
127 # Only leaves are actually drawn by the `material`.
131 # Mesh forming this model
134 # Material applied on this model
135 var material
: Material
137 redef var leaves
= [self]
140 # Material for models, or how to draw the model
142 # To create a simple basic blueish material, use `new Material`.
144 # Each class of material is associated to a `GLProgram` and its GPU shaders.
145 # The simple material `SmoothMaterial` allows to set an ambient, diffuse and specular color.
146 # To which `TextureMaterial` adds three textures, for each kind of light.
147 # The `NormalsMaterial` may be useful for debugging, it show the orientation of
148 # the normal vectors as colors.
151 # import gamnit::depth
153 # var blueish_material = new Material
154 # var redish_material = new SmoothMaterial([0.3, 0.0, 0.0],
157 # var normals_material = new NormalsMaterial
159 abstract class Material
161 # Draw a `model` from `actor`
163 # This method should be refined by subclasses as the default implementation is a no-op.
165 # This method is called on many materials for many `actor` and `model` at each frame.
166 # It is expected to use a `GLProgram` and call an equivalent to `glDrawArrays`.
167 # However, it should not call `glClear` nor `GamnitDisplay::flip`.
168 fun draw
(actor
: Actor, model
: LeafModel) do end
171 # Mesh with all geometry data
173 # May be created via `Plane`, `Cube` or `UVSphere`,
174 # or loaded from the assets folder indirectly with a `Model`.
177 # import gamnit::depth
179 # var plane = new Plane
180 # var cube = new Cube
181 # var sphere = new UVSphere(1.0, 32, 16)
185 # Vertices coordinates
186 var vertices
= new Array[Float] is lazy
, writable
188 # Indices to draw triangles with `glDrawElements`
190 # If `not_empty`, use `glDrawElements`, otherwise use `glDrawArrays`.
191 var indices
= new Array[Int] is lazy
, writable
193 private var indices_c
= new CUInt16Array.from
(indices
) is lazy
, writable
195 # Normals on each vertex
196 var normals
= new Array[Float] is lazy
, writable
198 # Coordinates on the texture per vertex
199 var texture_coords
= new Array[Float] is lazy
, writable
201 # `GLDrawMode` used to display this mesh, defaults to `gl_TRIANGLES`
202 fun draw_mode
: GLDrawMode do return gl_TRIANGLES
207 # Instances of this class define a light source position and type.
210 # TODO point light, spotlight, directional light, etc.
212 # Center of this light source in world coordinates
213 var position
= new Point3d[Float](0.0, 1000.0, 0.0)
218 # Live actors to be drawn on screen
219 var actors
= new Array[Actor]
221 # Single light of the scene
222 var light
= new Light
224 # TODO move `actors & light` to a scene object
225 # TODO support more than 1 light