]>
Dogcows Code - chaz/yoink/blob - src/Scene.cc
dc6ab75cac02f218bebd54d1b173382c64086389
2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
5 * Distributable under the terms and conditions of the 2-clause BSD license;
6 * see the file COPYING for a complete text of the license.
8 *****************************************************************************/
12 #include <moof/aabb.hh>
13 #include <moof/camera.hh>
14 #include <moof/entity.hh>
15 #include <moof/line.hh>
16 #include <moof/log.hh>
17 #include <moof/manager.hh>
18 #include <moof/math.hh>
19 #include <moof/resource.hh>
20 #include <moof/script.hh>
21 #include <moof/settings.hh>
22 #include <moof/sprite.hh>
24 #include "Character.hh"
28 struct Scene::impl
: public moof::manager
<impl
>
30 struct Quad
: public moof::entity
40 Quad(const moof::vector3
* vertices
[4],
41 const moof::image_handle
& texture
,
43 mTilemap(texture
, tileIndex
),
48 for (int i
= 0; i
< 4; ++i
)
50 mVertices
[i
] = *vertices
[i
];
51 //for (int j = 0; j < 3; ++j, ++num)
53 //mVertices[num] = (*vertices[i])[j];
57 aabb_
.enclose_vertices(mVertices
, 4);
58 sphere_
.point
= aabb_
.center();
59 sphere_
.radius
= (aabb_
.min
- sphere_
.point
).length();
62 void setBlending(bool blending
)
72 void setSurface(Surface type
)
77 Surface
getSurface() const
82 void draw(moof::scalar alpha
= 0.0) const
87 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
93 glFogi(GL_FOG_MODE
, GL_LINEAR
);
96 //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
97 mTilemap
.draw(mVertices
);
103 bool is_visible(const moof::frustum
& frustum
) const
105 return sphere_
.is_visible(frustum
);
109 moof::vector3 mVertices
[4];
111 moof::sprite mTilemap
;
120 moof::matrix4 mTransform
;
121 moof::image_handle mTexture
;
123 std::list
< boost::shared_ptr
<impl::Quad
> > mObjects
;
124 std::list
<moof::line2
> mLines
;
126 moof::aabb
<3> mBounds
;
137 void init(const std::string
& name
) {}
140 void importSceneBindings(moof::settings
& settings
, moof::script
& script
)
142 script
.import_function("SetBounds",
143 boost::bind(&impl::setBounds
, this, _1
));
144 script
.import_function("ResetTransform",
145 boost::bind(&impl::resetTransform
, this, _1
));
146 script
.import_function("Translate",
147 boost::bind(&impl::translate
, this, _1
));
148 script
.import_function("Scale",
149 boost::bind(&impl::scale
, this, _1
));
150 script
.import_function("Rotate",
151 boost::bind(&impl::rotate
, this, _1
));
152 script
.import_function("SetTexture",
153 boost::bind(&impl::setTexture
, this, _1
));
154 script
.import_function("DrawTilemap",
155 boost::bind(&impl::drawTilemap
, this, _1
));
156 script
.import_function("DrawTile",
157 boost::bind(&impl::drawTile
, this, _1
));
160 settings
.get("detail", detail
);
161 script
.globals().set_field("detail", detail
);
163 script
.globals().set_field("LOW", 1);
164 script
.globals().set_field("MEDIUM", 2);
165 script
.globals().set_field("HIGH", 3);
167 script
.globals().set_field("X", X
);
168 script
.globals().set_field("Y", Y
);
169 script
.globals().set_field("Z", Z
);
171 script
.globals().set_field("LEFT", Quad::LEFT
);
172 script
.globals().set_field("RIGHT", Quad::RIGHT
);
173 script
.globals().set_field("TOP", Quad::TOP
);
177 moof::script::status
load(moof::settings
& settings
, moof::script
& script
)
179 std::string path
= moof::resource::find_file("scenes/"+name(), "lua");
182 script
.push("the scene file could not be found");
183 return moof::script::file_error
;
186 importSceneBindings(settings
, script
);
187 return script
.do_file(path
);
191 static int loadBox(moof::script
& script
, moof::aabb3
& aabb
)
193 script
[1].require_table("point");
194 script
[2].require_table("point");
196 script
[1].push_field(1).get(aabb
.min
[0]);
197 script
[1].push_field(2).get(aabb
.min
[1]);
198 script
[1].push_field(3).get(aabb
.min
[2]);
199 script
[2].push_field(1).get(aabb
.max
[0]);
200 script
[2].push_field(2).get(aabb
.max
[1]);
201 script
[2].push_field(3).get(aabb
.max
[2]);
206 int setBounds(moof::script
& script
)
208 return loadBox(script
, mBounds
);
211 int resetTransform(moof::script
& script
)
213 mTransform
.identity();
217 int translate(moof::script
& script
)
220 script
[1].require_number().get(vec
[0]);
221 script
[2].require_number().get(vec
[1]);
222 script
[3].require_number().get(vec
[2]);
224 moof::matrix4 translation
;
225 moof::matrix_translation(translation
, vec
);
226 mTransform
= translation
* mTransform
;
231 int scale(moof::script
& script
)
233 int size
= script
.stack_size();
237 moof::scalar value
= 1.0;
238 script
[1].require_number().get(value
);
240 moof::matrix4 scaling
;
241 moof::matrix_uniform_scale(scaling
, value
);
242 mTransform
= scaling
* mTransform
;
247 script
[1].require_number().get(vec
[0]);
248 script
[2].require_number().get(vec
[1]);
249 script
[3].require_number().get(vec
[2]);
251 moof::matrix4 scaling
;
252 moof::matrix_scale(scaling
, vec
);
253 mTransform
= scaling
* mTransform
;
257 script
.top().raise("wrong number of arguments");
263 int rotate(moof::script
& script
)
268 script
[1].require_number().get(index
);
269 script
[2].require_number().get(value
);
271 moof::matrix_rotate_about_world_axis(mTransform
, index
, moof::rad(value
));
276 int setTexture(moof::script
& script
)
278 std::string texture_name
;
279 script
[1].require_string().get(texture_name
);
280 mTexture
= moof::resource::load(texture_name
, "png");
284 int drawTilemap(moof::script
& script
)
286 moof::script::slot table
= script
[1].require_table();
289 table
.get(width
, "width");
291 int nTiles
= table
.length();
292 if (nTiles
% width
!= 0)
294 table
.raise("invalid number of tiles");
297 if (width
== 0) table
.raise("width field must not be zero");
298 int height
= nTiles
/ width
;
300 moof::vector3 vertices
[height
+1][width
+1];
302 // the indices are stored upside-down in the scene file so that
303 // they are easier to edit as text, so we'll need to load them last
306 // do first row and first column of vertices
308 for (int w
= 0; w
<= width
; ++w
)
310 vertices
[height
][w
] = moof::demote(mTransform
*
311 moof::vector4(w
, height
, 0.0, 1.0));
313 for (int h
= 0; h
< height
; ++h
)
315 vertices
[h
][0] = moof::demote(mTransform
*
316 moof::vector4(0.0, h
, 0.0, 1.0));
320 for (int h
= height
- 1; h
>= 0; --h
)
322 for (int w
= 0; w
< width
; ++w
, ++i
)
330 vertices
[h
][wPlus1
] = moof::demote(mTransform
*
331 moof::vector4(wPlus1
, h
, 0.0, 1.0));
333 if (index
== moof::image::no_tile
) continue;
335 const moof::vector3
* corners
[4] = {
337 &vertices
[h
][wPlus1
],
338 &vertices
[hPlus1
][wPlus1
],
342 Quad
* quad
= new Quad(corners
, mTexture
, index
);
343 //quad->setSurface(surface);
345 boost::shared_ptr
<Quad
> quadPtr(quad
);
346 mObjects
.push_back(quadPtr
);
350 Quad::Surface surface
= Quad::NONE
;
351 table
.get(surface
, "surface");
353 if (surface
!= Quad::NONE
)
355 // need a 2d line for collisions
356 // assuming the camera always looks directly to -z when the
357 // scene is built, simply demoting the vector again should
358 // project the points to the xy-plane
360 moof::vector2 bl
= moof::demote(vertices
[0][0]);
361 moof::vector2 tr
= moof::demote(vertices
[height
][width
]);
363 mLines
.push_back(moof::line
<2>(bl
, tr
));
368 int drawTile(moof::script
& script
)
370 moof::script::slot param
= script
[1];
371 moof::script::slot top
= script
[-1];
375 bool blending
= false;
378 if (param
.is_table())
381 param
.get(width
, "u_scale");
382 param
.get(blending
, "blend");
383 param
.get(fog
, "fog");
385 else if (param
.is_number())
390 moof::vector3 vertices
[2][width
+1];
393 moof::scalar increment
= SCALAR(1.0) / moof::scalar(width
);
395 for (int h
= 0; h
<= 1; ++h
)
398 for (int w
= 0; w
<= width
; ++w
, xf
+= increment
)
400 vertices
[h
][w
] = moof::demote(mTransform
*
401 moof::vector4(xf
, moof::scalar(h
), 0.0, 1.0));
405 for (int w
= 0; w
< width
; ++w
)
409 const moof::vector3
* corners
[4] = {
411 &vertices
[0][wPlus1
],
412 &vertices
[1][wPlus1
],
416 Quad
* quad
= new Quad(corners
, mTexture
, index
);
417 quad
->setBlending(blending
);
420 boost::shared_ptr
<Quad
> quadPtr(quad
);
421 mObjects
.push_back(quadPtr
);
429 Scene::Scene(const std::string
& name
) :
431 impl_(Scene::impl::instance(name
)) {}
434 moof::script::status
Scene::load(moof::settings
& settings
, moof::script
& script
)
437 return impl_
->load(settings
, script
);
441 void Scene::draw(moof::scalar alpha
) const
443 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
444 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
446 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
451 impl_
->mBounds
.draw();
454 void Scene::draw_if_visible(moof::scalar alpha
,
455 const moof::frustum
& frustum
) const
457 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
458 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
460 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
462 (*it
)->draw_if_visible(alpha
, frustum
);
465 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
466 std::list
< moof::line
<2> >::const_iterator lit
;
468 for (lit
= lines
.begin(); lit
!= lines
.end(); ++lit
)
473 impl_
->mBounds
.draw();
477 bool Scene::castRay(const moof::ray
<2>& ray
,
478 std::list
<moof::ray
<2>::contact
>& hits
) const
480 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
481 std::list
< moof::line
<2> >::const_iterator it
;
483 for (it
= lines
.begin(); it
!= lines
.end(); ++it
)
485 moof::ray
<2>::contact hit
;
486 moof::scalar d
= (*it
).intersect_ray(ray
, hit
);
495 return !hits
.empty();
499 bool Scene::checkForCollision(Character
& character
)
503 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
504 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
507 moof::sphere
<3> sphere
= character
.sphere();
509 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
511 impl::Quad::Surface type
= (*it
)->getSurface();
512 if (type
== impl::Quad::NONE
) continue;
514 if (moof::checkCollision(sphere
, (*it
)->sphere()))
518 moof::vector2
impulse(0.0, 0.0);
519 moof::vector2 p
= character
.state().momentum
;
521 moof::state2 state
= character
.state(1.0);
522 sphere
= character
.sphere();
523 moof::scalar alpha
= 1.0;
524 while (moof::checkCollision(sphere
, (*it
)->sphere()))
527 state
= character
.state(alpha
);
530 character
.setPosition(state
.position
);
534 //case impl::Quad::TOP:
535 //if (p[1] < 0.0) impulse[1] = -p[1];
537 //case impl::Quad::LEFT:
538 //if (p[0] > 0.0) impulse[0] = 1.5*-p[0];
540 //case impl::Quad::RIGHT:
541 //if (p[0] < 0.0) impulse[0] = 1.5*-p[0];
545 //character.addImpulse(impulse);
551 moof::log_info
<< "collisions: " << collisions
<< std::endl
;
This page took 0.057734 seconds and 4 git commands to generate.