-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscene.m
More file actions
117 lines (96 loc) · 4.77 KB
/
Copy pathscene.m
File metadata and controls
117 lines (96 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
:- module scene.
%==============================================================================%
:- interface.
%==============================================================================%
:- use_module render.
:- use_module camera.
:- use_module mglow.
%------------------------------------------------------------------------------%
:- include_module scene.matrix_tree.
:- include_module scene.node_tree.
:- use_module scene.matrix_tree.
:- use_module scene.node_tree.
%------------------------------------------------------------------------------%
:- type scene(Model, Heightmap, Texture) --->
scene(scene.matrix_tree.matrix_tree,
scene.node_tree.node(Model),
camera.camera, skybox::Texture,
heightmap::Heightmap, ground::Texture).
%------------------------------------------------------------------------------%
% Recursively draws all nodes in the tree.
:- pred draw(
scene.matrix_tree.matrix_tree::in,
scene.node_tree.node(Model)::in,
Render::in, mglow.window::di, mglow.window::uo) is det
<= (render.model(Render, Model)).
:- pred draw(scene(Model, Heightmap, Texture)::in, Render::in,
mglow.window::di, mglow.window::uo) is det <=
(render.model(Render, Model),
render.skybox(Render, Texture),
render.heightmap(Render, Heightmap, Texture)).
% Similar to draw. First applies the given transformation without pushing
% matrices on the renderer, and will pass any further transfom nodes into
% another call to apply_transformation. This is an optimization to use a
% single matrix stack entry to handle multiple transformations in a row.
:- pred apply_transformation_and_draw(scene.matrix_tree.matrix_tree::in,
Render::in, scene.matrix_tree.transformation::in,
scene.node_tree.node(Model)::in, mglow.window::di, mglow.window::uo) is det
<= render.model(Render, Model).
% Translates scene.matrix_tree.transformation types into calls to render
% typeclass predicates.
:- pred apply_transformation(scene.matrix_tree.transformation::in, Render::in,
mglow.window::di, mglow.window::uo) is det <= render.render(Render).
%==============================================================================%
:- implementation.
%==============================================================================%
apply_transformation_and_draw(Tree, Render, Transformation, Node, !Window) :-
apply_transformation(Transformation, Render, !Window),
( Node = scene.node_tree.transform(NextTransformation, NextNode) ->
apply_transformation_and_draw(Tree,
Render, NextTransformation, NextNode, !Window)
;
draw(Tree, Node, Render, !Window)
).
draw(Tree, scene.node_tree.transform(Transformation, Node), Render, !Window) :-
render.push_matrix(Render, !Window),
apply_transformation_and_draw(Tree, Render, Transformation, Node, !Window),
render.pop_matrix(Render, !Window).
draw(_, scene.node_tree.model(Model), Render, !Window) :-
render.draw(Render, Model, !Window).
draw(Tree, scene.node_tree.group(NodeA, NodeB), Render, !Window) :-
draw(Tree, NodeA, Render, !Window),
draw(Tree, NodeB, Render, !Window).
draw(Scene, Render, !Window) :-
Scene = scene(MatrixTree, NodeTree, Camera, Skybox, Heightmap, Ground),
Pitch = Camera ^ camera.pitch,
Yaw = Camera ^ camera.yaw,
render.draw_skybox(Render, Pitch, Yaw, Skybox, !Window),
render.push_matrix(Render, !Window),
render.rotate_x(Render, Pitch, !Window),
render.rotate_y(Render, Yaw, !Window),
X = Camera ^ camera.x, Y = Camera ^ camera.y, Z = Camera ^ camera.z,
render.translate(Render, X, Y, Z, !Window),
render.scale(Render, 1.0, 10.0, 1.0, !Window),
render.draw_heightmap(Render, Heightmap, Ground, !Window),
render.scale(Render, 1.0, 0.1, 1.0, !Window),
% If the first node is a transformation, we can avoid another matrix stack
% manipulation and just ride on the push and pop in this outer function.
( NodeTree = scene.node_tree.transform(Transformation, Node) ->
apply_transformation(Transformation, Render, !Window),
draw(MatrixTree, Node, Render, !Window)
;
draw(MatrixTree, NodeTree, Render, !Window)
),
render.pop_matrix(Render, !Window).
% TODO
apply_transformation(scene.matrix_tree.scale(_, _, _), _, !Window).
% TODO
apply_transformation(scene.matrix_tree.matrix(_), _, !Window).
apply_transformation(scene.matrix_tree.translate(X, Y, Z), Render, !Window) :-
render.translate(Render, X, Y, Z, !Window).
apply_transformation(scene.matrix_tree.rotate_x(A), Render, !Window) :-
render.rotate_x(Render, A, !Window).
apply_transformation(scene.matrix_tree.rotate_y(A), Render, !Window) :-
render.rotate_y(Render, A, !Window).
apply_transformation(scene.matrix_tree.rotate_z(A), Render, !Window) :-
render.rotate_z(Render, A, !Window).