]>
Dogcows Code - chaz/yoink/blob - src/Scene.cc
af54c28768cfa92af735ccb9858d211f0a0789b2
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
14 #include <moof/aabb.hh>
15 #include <moof/camera.hh>
16 #include <moof/entity.hh>
17 #include <moof/line.hh>
18 #include <moof/log.hh>
19 #include <moof/manager.hh>
20 #include <moof/math.hh>
21 #include <moof/resource.hh>
22 #include <moof/script.hh>
23 #include <moof/settings.hh>
24 #include <moof/sprite.hh>
26 #include "Character.hh"
30 struct Scene::impl
: public moof::manager
<impl
>
32 struct Quad
: public moof::entity
42 Quad(const moof::vector3
* vertices
[4],
43 const moof::image_handle
& texture
,
45 mTilemap(texture
, tileIndex
),
50 for (int i
= 0; i
< 4; ++i
)
52 mVertices
[i
] = *vertices
[i
];
53 //for (int j = 0; j < 3; ++j, ++num)
55 //mVertices[num] = (*vertices[i])[j];
59 aabb_
.enclose_vertices(mVertices
, 4);
60 sphere_
.point
= aabb_
.center();
61 sphere_
.radius
= (aabb_
.min
- sphere_
.point
).length();
64 void setBlending(bool blending
)
74 void setSurface(Surface type
)
79 Surface
getSurface() const
84 void draw(moof::scalar alpha
= 0.0) const
89 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
95 glFogi(GL_FOG_MODE
, GL_LINEAR
);
98 //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
99 mTilemap
.draw(mVertices
);
105 bool is_visible(const moof::frustum
& frustum
) const
107 return sphere_
.is_visible(frustum
);
111 moof::vector3 mVertices
[4];
113 moof::sprite mTilemap
;
122 moof::matrix4 mTransform
;
123 moof::image_handle mTexture
;
125 std::list
< boost::shared_ptr
<impl::Quad
> > mObjects
;
126 std::list
<moof::line2
> mLines
;
128 moof::aabb
<3> mBounds
;
139 void init(const std::string
& name
) {}
142 void importSceneBindings(moof::settings
& settings
, moof::script
& script
)
144 script
.import_function("SetBounds",
145 boost::bind(&impl::setBounds
, this, _1
));
146 script
.import_function("ResetTransform",
147 boost::bind(&impl::resetTransform
, this, _1
));
148 script
.import_function("Translate",
149 boost::bind(&impl::translate
, this, _1
));
150 script
.import_function("Scale",
151 boost::bind(&impl::scale
, this, _1
));
152 script
.import_function("Rotate",
153 boost::bind(&impl::rotate
, this, _1
));
154 script
.import_function("SetTexture",
155 boost::bind(&impl::setTexture
, this, _1
));
156 script
.import_function("DrawTilemap",
157 boost::bind(&impl::drawTilemap
, this, _1
));
158 script
.import_function("DrawTile",
159 boost::bind(&impl::drawTile
, this, _1
));
162 settings
.get("detail", detail
);
163 script
.globals().set_field("detail", detail
);
165 script
.globals().set_field("LOW", 1);
166 script
.globals().set_field("MEDIUM", 2);
167 script
.globals().set_field("HIGH", 3);
169 script
.globals().set_field("X", X
);
170 script
.globals().set_field("Y", Y
);
171 script
.globals().set_field("Z", Z
);
173 script
.globals().set_field("LEFT", Quad::LEFT
);
174 script
.globals().set_field("RIGHT", Quad::RIGHT
);
175 script
.globals().set_field("TOP", Quad::TOP
);
179 moof::script::status
load(moof::settings
& settings
, moof::script
& script
)
181 std::string path
= moof::resource::find_file("scenes/"+name(), "lua");
184 script
.push("the scene file could not be found");
185 return moof::script::file_error
;
188 importSceneBindings(settings
, script
);
189 return script
.do_file(path
);
193 static int loadBox(moof::script
& script
, moof::aabb3
& aabb
)
195 script
[1].require_table("point");
196 script
[2].require_table("point");
198 script
[1].push_field(1).get(aabb
.min
[0]);
199 script
[1].push_field(2).get(aabb
.min
[1]);
200 script
[1].push_field(3).get(aabb
.min
[2]);
201 script
[2].push_field(1).get(aabb
.max
[0]);
202 script
[2].push_field(2).get(aabb
.max
[1]);
203 script
[2].push_field(3).get(aabb
.max
[2]);
208 int setBounds(moof::script
& script
)
210 return loadBox(script
, mBounds
);
213 int resetTransform(moof::script
& script
)
215 mTransform
.identity();
219 int translate(moof::script
& script
)
222 script
[1].require_number().get(vec
[0]);
223 script
[2].require_number().get(vec
[1]);
224 script
[3].require_number().get(vec
[2]);
226 moof::matrix4 translation
;
227 moof::matrix_translation(translation
, vec
);
228 mTransform
= translation
* mTransform
;
233 int scale(moof::script
& script
)
235 int size
= script
.stack_size();
239 moof::scalar value
= 1.0;
240 script
[1].require_number().get(value
);
242 moof::matrix4 scaling
;
243 moof::matrix_uniform_scale(scaling
, value
);
244 mTransform
= scaling
* mTransform
;
249 script
[1].require_number().get(vec
[0]);
250 script
[2].require_number().get(vec
[1]);
251 script
[3].require_number().get(vec
[2]);
253 moof::matrix4 scaling
;
254 moof::matrix_scale(scaling
, vec
);
255 mTransform
= scaling
* mTransform
;
259 script
.top().raise("wrong number of arguments");
265 int rotate(moof::script
& script
)
270 script
[1].require_number().get(index
);
271 script
[2].require_number().get(value
);
273 moof::matrix_rotate_about_world_axis(mTransform
, index
,
279 int setTexture(moof::script
& script
)
281 std::string texture_name
;
282 script
[1].require_string().get(texture_name
);
283 mTexture
= moof::resource::load(texture_name
, "png");
287 int drawTilemap(moof::script
& script
)
289 moof::script::slot table
= script
[1].require_table();
292 table
.get(width
, "width");
294 int nTiles
= table
.length();
295 if (nTiles
% width
!= 0)
297 table
.raise("invalid number of tiles");
300 if (width
== 0) table
.raise("width field must not be zero");
301 int height
= nTiles
/ width
;
303 moof::vector3 vertices
[height
+1][width
+1];
305 // the indices are stored upside-down in the scene file so that
306 // they are easier to edit as text, so we'll need to load them last
309 // do first row and first column of vertices
311 for (int w
= 0; w
<= width
; ++w
)
313 vertices
[height
][w
] = moof::demote(mTransform
*
314 moof::vector4(w
, height
, 0.0, 1.0));
316 for (int h
= 0; h
< height
; ++h
)
318 vertices
[h
][0] = moof::demote(mTransform
*
319 moof::vector4(0.0, h
, 0.0, 1.0));
323 for (int h
= height
- 1; h
>= 0; --h
)
325 for (int w
= 0; w
< width
; ++w
, ++i
)
333 vertices
[h
][wPlus1
] = moof::demote(mTransform
*
334 moof::vector4(wPlus1
, h
, 0.0, 1.0));
336 if (index
== moof::image::no_tile
) continue;
338 const moof::vector3
* corners
[4] = {
340 &vertices
[h
][wPlus1
],
341 &vertices
[hPlus1
][wPlus1
],
345 Quad
* quad
= new Quad(corners
, mTexture
, index
);
346 //quad->setSurface(surface);
348 boost::shared_ptr
<Quad
> quadPtr(quad
);
349 mObjects
.push_back(quadPtr
);
353 Quad::Surface surface
= Quad::NONE
;
354 table
.get(surface
, "surface");
356 if (surface
!= Quad::NONE
)
358 // need a 2d line for collisions
359 // assuming the camera always looks directly to -z when the
360 // scene is built, simply demoting the vector again should
361 // project the points to the xy-plane
363 moof::vector2 bl
= moof::demote(vertices
[0][0]);
364 moof::vector2 tr
= moof::demote(vertices
[height
][width
]);
366 mLines
.push_back(moof::line
<2>(bl
, tr
));
372 int drawTile(moof::script
& script
)
374 moof::script::slot param
= script
[1];
375 moof::script::slot top
= script
[-1];
379 bool blending
= false;
382 if (param
.is_table())
385 param
.get(width
, "u_scale");
386 param
.get(blending
, "blend");
387 param
.get(fog
, "fog");
389 else if (param
.is_number())
394 moof::vector3 vertices
[2][width
+1];
397 moof::scalar increment
= SCALAR(1.0) / moof::scalar(width
);
399 for (int h
= 0; h
<= 1; ++h
)
402 for (int w
= 0; w
<= width
; ++w
, xf
+= increment
)
404 vertices
[h
][w
] = moof::demote(mTransform
*
405 moof::vector4(xf
, moof::scalar(h
), 0.0, 1.0));
409 for (int w
= 0; w
< width
; ++w
)
413 const moof::vector3
* corners
[4] = {
415 &vertices
[0][wPlus1
],
416 &vertices
[1][wPlus1
],
420 Quad
* quad
= new Quad(corners
, mTexture
, index
);
421 quad
->setBlending(blending
);
424 boost::shared_ptr
<Quad
> quadPtr(quad
);
425 mObjects
.push_back(quadPtr
);
433 Scene::Scene(const std::string
& name
) :
435 impl_(Scene::impl::instance(name
)) {}
438 moof::script::status
Scene::load(moof::settings
& settings
, moof::script
& script
)
441 return impl_
->load(settings
, script
);
445 void Scene::draw(moof::scalar alpha
) const
447 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
448 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
450 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
455 impl_
->mBounds
.draw();
458 void Scene::draw_if_visible(moof::scalar alpha
,
459 const moof::frustum
& frustum
) const
461 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
462 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
464 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
466 (*it
)->draw_if_visible(alpha
, frustum
);
469 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
470 std::list
< moof::line
<2> >::const_iterator lit
;
472 for (lit
= lines
.begin(); lit
!= lines
.end(); ++lit
)
477 impl_
->mBounds
.draw();
481 bool Scene::castRay(const moof::ray
<2>& ray
,
482 std::list
<moof::ray
<2>::contact
>& hits
) const
484 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
485 std::list
< moof::line
<2> >::const_iterator it
;
487 for (it
= lines
.begin(); it
!= lines
.end(); ++it
)
489 moof::ray
<2>::contact hit
;
490 moof::scalar d
= (*it
).intersect_ray(ray
, hit
);
499 return !hits
.empty();
503 bool Scene::checkForCollision(Character
& character
)
507 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
508 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
511 moof::sphere
<3> sphere
= character
.sphere();
513 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
515 impl::Quad::Surface type
= (*it
)->getSurface();
516 if (type
== impl::Quad::NONE
) continue;
518 if (moof::checkCollision(sphere
, (*it
)->sphere()))
522 moof::vector2
impulse(0.0, 0.0);
523 moof::vector2 p
= character
.state().momentum
;
525 moof::state2 state
= character
.state(1.0);
526 sphere
= character
.sphere();
527 moof::scalar alpha
= 1.0;
528 while (moof::checkCollision(sphere
, (*it
)->sphere()))
531 state
= character
.state(alpha
);
534 character
.setPosition(state
.position
);
538 //case impl::Quad::TOP:
539 //if (p[1] < 0.0) impulse[1] = -p[1];
541 //case impl::Quad::LEFT:
542 //if (p[0] > 0.0) impulse[0] = 1.5*-p[0];
544 //case impl::Quad::RIGHT:
545 //if (p[0] < 0.0) impulse[0] = 1.5*-p[0];
549 //character.addImpulse(impulse);
555 moof::log_info
<< "collisions: " << collisions
<< std::endl
;
This page took 0.059245 seconds and 4 git commands to generate.