1 module armos.graphics.primitives;
2 import armos.graphics;
3 import armos.math;
4 import std.math;
5 
6 /++
7 箱状のMeshを返します.
8 +/
9 armos.graphics.Mesh boxPrimitive(in armos.math.Vector3f position, in armos.math.Vector3f size){
10     auto mesh = new armos.graphics.Mesh;
11 
12     auto halfSize = size*0.5;
13     mesh.primitiveMode = armos.graphics.PrimitiveMode.Triangles;
14 
15     mesh.addVertex(armos.math.Vector3f( -halfSize[0], -halfSize[1], -halfSize[2]  )+position);
16     mesh.addVertex(armos.math.Vector3f( halfSize[0],  -halfSize[1], -halfSize[2]  )+position);
17     mesh.addVertex(armos.math.Vector3f( halfSize[0],  halfSize[1],  -halfSize[2]  )+position);
18     mesh.addVertex(armos.math.Vector3f( -halfSize[0], halfSize[1],  -halfSize[2]  )+position);
19 
20     mesh.addVertex(armos.math.Vector3f( -halfSize[0],  halfSize[1], halfSize[2] )+position);
21     mesh.addVertex(armos.math.Vector3f( halfSize[0], halfSize[1], halfSize[2] )+position);
22     mesh.addVertex(armos.math.Vector3f( halfSize[0], -halfSize[1],  halfSize[2] )+position);
23     mesh.addVertex(armos.math.Vector3f( -halfSize[0], -halfSize[1],  halfSize[2] )+position);
24 
25     mesh.addIndex(0);
26     mesh.addIndex(2);
27     mesh.addIndex(1);
28 
29     mesh.addIndex(0);
30     mesh.addIndex(3);
31     mesh.addIndex(2);
32 
33     mesh.addIndex(4);
34     mesh.addIndex(6);
35     mesh.addIndex(5);
36 
37     mesh.addIndex(4);
38     mesh.addIndex(7);
39     mesh.addIndex(6);
40     //
41     //
42     mesh.addIndex(2);
43     mesh.addIndex(3);
44     mesh.addIndex(5);
45 
46     mesh.addIndex(3);
47     mesh.addIndex(4);
48     mesh.addIndex(5);
49 
50     mesh.addIndex(0);
51     mesh.addIndex(1);
52     mesh.addIndex(6);
53 
54     mesh.addIndex(0);
55     mesh.addIndex(6);
56     mesh.addIndex(7);
57 
58     mesh.addIndex(1);
59     mesh.addIndex(2);
60     mesh.addIndex(5);
61 
62     mesh.addIndex(1);
63     mesh.addIndex(5);
64     mesh.addIndex(6);
65 
66     mesh.addIndex(0);
67     mesh.addIndex(7);
68     mesh.addIndex(3);
69 
70     mesh.addIndex(3);
71     mesh.addIndex(7);
72     mesh.addIndex(4);
73     return mesh;
74 }
75 
76 armos.graphics.Mesh boxFramePrimitive(in armos.math.Vector3f position, in armos.math.Vector3f size){
77     auto mesh = new armos.graphics.Mesh;
78 
79     auto halfSize = size*0.5;
80     mesh.primitiveMode = armos.graphics.PrimitiveMode.Lines;
81 
82     mesh.addVertex(armos.math.Vector3f( -halfSize[0], -halfSize[1], -halfSize[2]  )+position);
83     mesh.addVertex(armos.math.Vector3f( halfSize[0],  -halfSize[1], -halfSize[2]  )+position);
84     mesh.addVertex(armos.math.Vector3f( halfSize[0],  halfSize[1],  -halfSize[2]  )+position);
85     mesh.addVertex(armos.math.Vector3f( -halfSize[0], halfSize[1],  -halfSize[2]  )+position);
86 
87     mesh.addVertex(armos.math.Vector3f( -halfSize[0], -halfSize[1], halfSize[2] )+position);
88     mesh.addVertex(armos.math.Vector3f( halfSize[0],  -halfSize[1], halfSize[2] )+position);
89     mesh.addVertex(armos.math.Vector3f( halfSize[0],  halfSize[1],  halfSize[2] )+position);
90     mesh.addVertex(armos.math.Vector3f( -halfSize[0], halfSize[1],  halfSize[2] )+position);
91 
92     mesh.addIndex(0); mesh.addIndex(1);
93     mesh.addIndex(1); mesh.addIndex(2);
94     mesh.addIndex(3); mesh.addIndex(2);
95     mesh.addIndex(3); mesh.addIndex(0);
96 
97     mesh.addIndex(4); mesh.addIndex(5);
98     mesh.addIndex(5); mesh.addIndex(6);
99     mesh.addIndex(6); mesh.addIndex(7);
100     mesh.addIndex(7); mesh.addIndex(4);
101     
102     mesh.addIndex(0); mesh.addIndex(4);
103     mesh.addIndex(1); mesh.addIndex(5);
104     mesh.addIndex(2); mesh.addIndex(6);
105     mesh.addIndex(3); mesh.addIndex(7);
106     return mesh;
107 }
108 
109 /++
110 連続した線のMeshを返します.
111 Params:
112 arr = 線の頂点です.任意の個数設定できます.
113 +/
114 armos.graphics.Mesh linePrimitive(armos.math.Vector3f[] arr ...){
115     if (arr.length < 2) {
116         assert(0);
117     }
118     auto mesh = new armos.graphics.Mesh;
119     mesh.primitiveMode = armos.graphics.PrimitiveMode.LineStrip ;
120     foreach (int index, vec; arr) {
121         mesh.addVertex(vec);
122         mesh.addIndex(index);
123     }
124     return mesh;
125 }
126 
127 /++
128 球体のMeshを返します.
129 Deprecated: 現在動作しません.
130 +/
131 armos.graphics.Mesh spherePrimitive(){
132     auto mesh = new armos.graphics.Mesh;
133     return mesh;
134 }
135 
136 /++
137 円錐のMeshを返します.
138 Deprecated: 現在動作しません.
139 +/
140 armos.graphics.Mesh conePrimitive(){
141     auto mesh = new armos.graphics.Mesh;
142     return mesh;
143 }
144 
145 /++
146 円筒のMeshを返します.
147 Deprecated: 現在動作しません.
148 +/
149 armos.graphics.Mesh cylinderPrimitive(){
150     auto mesh = new armos.graphics.Mesh;
151     return mesh;
152 }
153 
154 /++
155 多面体のMeshを返します.
156 Deprecated: 現在動作しません.
157 +/
158 armos.graphics.Mesh icoSpherePrimitive(){
159     auto mesh = new armos.graphics.Mesh;
160     return mesh;
161 }
162 
163 /++
164 円盤のMeshを返します.
165 Params:
166 position = 円盤の中心の座標を指定します.
167 radius = 円盤の半径を指定します.
168 resolution = 円盤の分割数を指定します.
169 +/
170 armos.graphics.Mesh circlePrimitive(in armos.math.Vector3f position, in float radius, in int resolution = 12){
171     auto mesh = new armos.graphics.Mesh;
172     for (int i = 0; i < resolution; i++) {
173         mesh.addVertex(position);
174         mesh.addVertex(position+armos.math.Vector3f(
175                     radius*cos(cast(float)i/cast(float)resolution*2.0*PI),
176                     radius*sin(cast(float)i/cast(float)resolution*2.0*PI),
177                     0
178                     ));
179         mesh.addVertex(position+armos.math.Vector3f(
180                     radius*cos(cast(float)(i+1)/cast(float)resolution*2.0*PI),
181                     radius*sin(cast(float)(i+1)/cast(float)resolution*2.0*PI),
182                     0
183                     ));
184     }
185     for (int i = 0; i < resolution*3; i++) {
186         mesh.addIndex(i);
187     }
188     return mesh;
189 }
190 
191 /++
192 円盤のMeshを返します.
193 Params:
194 x = 円盤の中心のX座標を指定します.
195 y = 円盤の中心のY座標を指定します.
196 z = 円盤の中心のZ座標を指定します.
197 radius = 円盤の半径を指定します.
198 resolution = 円盤の分割数を指定します.
199 +/
200 armos.graphics.Mesh circlePrimitive(in float x, in float y, in float z, in float radius, in int resolution = 12){
201     return circlePrimitive(armos.math.Vector3f(x, y, z), radius, resolution);
202 }
203 
204 /++
205 長方形のMeshを返します.
206 Params:
207 position = 長方形の中心の座標を指定します.
208 size = 長方形の大きさを指定します.
209 +/
210 armos.graphics.Mesh planePrimitive(in armos.math.Vector3f position, in armos.math.Vector2f size){
211     auto mesh = new armos.graphics.Mesh;
212     mesh.primitiveMode = armos.graphics.PrimitiveMode.Triangles;
213     mesh.vertices = [
214         armos.math.Vector4f( -size[0]*0.5, -size[1]*0.5, 0, 1), 
215         armos.math.Vector4f( -size[0]*0.5,  size[1]*0.5, 0, 1), 
216         armos.math.Vector4f( size[0]*0.5,  size[1]*0.5,  0, 1), 
217         armos.math.Vector4f( size[0]*0.5, -size[1]*0.5,  0, 1), 
218     ];
219     
220     mesh.indices = [
221         0, 1, 2,
222         2, 3, 0,
223     ];
224     return mesh;
225 }
226 
227 /++
228 長方形のMeshを返します.
229 Params:
230 x = 長方形の中心のX座標を指定します.
231 y = 長方形の中心のY座標を指定します.
232 z = 長方形の中心のZ座標を指定します.
233 w = 長方形のX方向の大きさを指定します.
234 h = 長方形のY方向の大きさを指定します.
235 +/
236 armos.graphics.Mesh planePrimitive(in float x, in float y, in float z, in float w, in float h){
237     return planePrimitive(armos.math.Vector3f(x, y, z), armos.math.Vector2f(w, h));
238 }