2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *******************************************************************************/
39 #include "Settings.hh"
46 static std::string
getPath(const std::string
& name
)
48 return Resource::getPath("scenes/" + name
+ ".lua");
61 octree
= Octree::alloc(Aabb());
64 static int loadBox(Script
& script
, Aabb
& aabb
)
66 Script::Value table
[] = {script
[1], script
[2]};
68 if (!table
[0].isTable() || !table
[1].isTable())
70 logWarning("wrong arguments to setPlayfieldBounds; ignoring...");
74 for (int i
= 0; i
<= 1; ++i
)
76 for (int j
= 1; j
<= 3; ++j
)
83 script
[3].get(aabb
.min
[0]);
84 script
[4].get(aabb
.min
[1]);
85 script
[5].get(aabb
.min
[2]);
86 script
[6].get(aabb
.max
[0]);
87 script
[7].get(aabb
.max
[1]);
88 script
[8].get(aabb
.max
[2]);
93 int setPlayfieldBounds(Script
& script
)
96 return loadBox(script
, bounds
);
99 int setMaximumBounds(Script
& script
)
102 int ret
= loadBox(script
, bounds
);
103 octree
= Octree::alloc(bounds
);
107 int resetTransform(Script
& script
)
109 transform
.identity();
113 int translate(Script
& script
)
115 Script::Value x
= script
[1];
116 Script::Value y
= script
[2];
117 Script::Value z
= script
[3];
119 if (!x
.isNumber() || !y
.isNumber() || !z
.isNumber())
121 logWarning("wrong arguments to translate; ignoring...");
131 cml::matrix_translation(translation
, vec
);
132 transform
= translation
* transform
;
137 int scale(Script
& script
)
139 if (script
.getSize() == 3)
142 script
[1].get(vec
[0]);
143 script
[2].get(vec
[1]);
144 script
[3].get(vec
[2]);
147 cml::matrix_scale(scaling
, vec
);
148 transform
= scaling
* transform
;
150 else if (script
.getSize() == 1)
153 script
[1].get(value
);
156 cml::matrix_uniform_scale(scaling
,
158 transform
= scaling
* transform
;
162 logWarning("wrong arguments to scale; ignoring...");
168 int rotate(Script
& script
)
170 Script::Value a
= script
[1];
171 Script::Value d
= script
[2];
173 if (!a
.isString() || !d
.isNumber())
175 logWarning("wrong arguments to rotate; ignoring...");
183 if (axis
== "x") index
= 0;
184 else if (axis
== "y") index
= 1;
185 else if (axis
== "z") index
= 2;
190 cml::matrix_rotate_about_world_axis(transform
,
191 index
, cml::rad(Scalar(value
)));
196 int setTexture(Script
& script
)
198 Script::Value t
= script
[1];
200 if (t
.isString()) t
.get(texture
);
201 else logWarning("wrong arguments to setTexture; ignoring...");
206 int makeTilemap(Script
& script
)
208 Script::Value table
= script
[1];
209 Script::Value top
= script
[-1];
211 if (!table
.isTable())
213 logWarning("wrong arguments to makeTilemap; ignoring...");
220 table
.pushField("width");
225 table
.pushField("tiles");
226 Script::Value tiles
= script
.getTop();
227 nTiles
= tiles
.getLength();
229 std::vector
< std::vector
<Tilemap::Index
> > indices
;
231 if (nTiles
% width
== 0)
235 height
= nTiles
/ width
;
236 indices
.resize(height
);
238 // the indices are stored upside-down in the scene file so that they
239 // are easier to edit as text, so we'll need to load them last row
243 for (h
= height
- 1; h
>= 0; --h
)
245 std::vector
<Tilemap::Index
> row
;
247 for (w
= 0; w
< width
; ++w
, ++i
)
249 script
.checkStack(2);
250 script
.push(long(i
));
256 row
.push_back(Tilemap::Index(index
));
264 logError("invalid tiles in tilemap instruction");
268 Vector4 vertices
[height
+1][width
+1];
270 Matrix4 transposedTransform
= transform
;
271 transposedTransform
.transpose();
273 for (int h
= 0; h
<= height
; ++h
)
275 for (int w
= 0; w
<= width
; ++w
)
277 vertices
[h
][w
] = Vector4(Scalar(w
), Scalar(h
), 0.0, 1.0) *
282 for (int h
= 0; h
< height
; ++h
)
284 for (int w
= 0; w
< width
; ++w
)
286 if (indices
[h
][w
] == Tilemap::NO_TILE
) continue;
288 Vector3 quadVertices
[4];
290 demoteVector(quadVertices
[0], vertices
[h
][w
]);
291 demoteVector(quadVertices
[1], vertices
[h
][w
+1]);
292 demoteVector(quadVertices
[2], vertices
[h
+1][w
+1]);
293 demoteVector(quadVertices
[3], vertices
[h
+1][w
]);
295 Quad
* quad
= new Quad(quadVertices
, texture
, indices
[h
][w
]);
296 boost::shared_ptr
<Quad
> quadPtr(quad
);
298 octree
->insert(quadPtr
);
305 int makeBillboard(Script
& script
)
307 Script::Value table
= script
[1];
308 Script::Value top
= script
[-1];
312 bool blending
= false;
317 table
.pushField("tile");
318 if (top
.isNumber()) top
.get(index
);
320 table
.pushField("u_scale");
321 if (top
.isNumber()) top
.get(width
);
323 table
.pushField("blend");
324 if (top
.isBoolean()) top
.get(blending
);
326 table
.pushField("fog");
327 if (top
.isBoolean()) top
.get(fog
);
330 Vector4 vertices
[2][width
+1];
332 Matrix4 transposedTransform
= transform
;
333 transposedTransform
.transpose();
336 Scalar increment
= 1.0 / Scalar(width
);
338 for (int h
= 0; h
<= 1; ++h
)
341 for (int w
= 0; w
<= width
; ++w
, xf
+= increment
)
343 vertices
[h
][w
] = Vector4(xf
, Scalar(h
), 0.0, 1.0) *
348 for (int w
= 0; w
< width
; ++w
)
350 Vector3 quadVertices
[4];
352 demoteVector(quadVertices
[0], vertices
[0][w
]);
353 demoteVector(quadVertices
[1], vertices
[0][w
+1]);
354 demoteVector(quadVertices
[2], vertices
[1][w
+1]);
355 demoteVector(quadVertices
[3], vertices
[1][w
]);
357 Quad
* quad
= new Quad(quadVertices
, texture
, Tilemap::Index(index
));
358 quad
->setBlending(blending
);
361 boost::shared_ptr
<Quad
> quadPtr(quad
);
363 octree
->insert(quadPtr
);
371 static void importScriptBindings(Script
& script
, Meh
& scene
)
373 script
.importFunction("SetPlayfieldBounds",
374 boost::bind(&Meh::setPlayfieldBounds
, &scene
, _1
));
375 script
.importFunction("SetMaximumBounds",
376 boost::bind(&Meh::setMaximumBounds
, &scene
, _1
));
377 script
.importFunction("ResetTransform",
378 boost::bind(&Meh::resetTransform
, &scene
, _1
));
379 script
.importFunction("Translate",
380 boost::bind(&Meh::translate
, &scene
, _1
));
381 script
.importFunction("Scale",
382 boost::bind(&Meh::scale
, &scene
, _1
));
383 script
.importFunction("Rotate",
384 boost::bind(&Meh::rotate
, &scene
, _1
));
385 script
.importFunction("SetTexture",
386 boost::bind(&Meh::setTexture
, &scene
, _1
));
387 script
.importFunction("MakeTilemap",
388 boost::bind(&Meh::makeTilemap
, &scene
, _1
));
389 script
.importFunction("MakeBillboard",
390 boost::bind(&Meh::makeBillboard
, &scene
, _1
));
394 OctreeP
loadScene(const std::string
& name
)
396 std::string filePath
= getPath(name
);
401 script
.importStandardLibraries();
402 importLogScript(script
);
403 importScriptBindings(script
, cool
);
406 Settings::getInstance().get("detail", detail
);
409 script
.set("detail");
411 logInfo("doing file...");
412 if (script
.doFile(filePath
) != 0)
416 logError("lua error: %s", str
.c_str());
427 /** vim: set ts=4 sw=4 tw=80: *************************************************/