]>
Dogcows Code - chaz/yoink/blob - src/Scene.cc
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/script.hh>
22 #include <moof/settings.hh>
23 #include <moof/sprite.hh>
25 #include "Character.hh"
29 struct Scene::impl
: public moof::manager
<impl
>
31 struct Quad
: public moof::entity
41 Quad(const moof::vector3
* vertices
[4],
42 const std::string
& texture
,
44 mTilemap(texture
, tileIndex
),
49 for (int i
= 0; i
< 4; ++i
)
51 mVertices
[i
] = *vertices
[i
];
52 //for (int j = 0; j < 3; ++j, ++num)
54 //mVertices[num] = (*vertices[i])[j];
58 aabb_
.enclose_vertices(mVertices
, 4);
59 sphere_
.point
= aabb_
.center();
60 sphere_
.radius
= (aabb_
.min
- sphere_
.point
).length();
63 void setBlending(bool blending
)
73 void setSurface(Surface type
)
78 Surface
getSurface() const
83 void draw(moof::scalar alpha
= 0.0) const
88 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
94 glFogi(GL_FOG_MODE
, GL_LINEAR
);
97 //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
98 mTilemap
.draw(mVertices
);
104 bool is_visible(const moof::frustum
& frustum
) const
106 return sphere_
.is_visible(frustum
);
110 moof::vector3 mVertices
[4];
112 moof::sprite mTilemap
;
121 moof::matrix4 mTransform
;
122 std::string mTexture
;
124 std::list
< boost::shared_ptr
<impl::Quad
> > mObjects
;
125 std::list
<moof::line2
> mLines
;
127 moof::aabb
<3> mBounds
;
138 void init(const std::string
& name
) {}
141 void importSceneBindings(moof::settings
& settings
, moof::script
& script
)
143 script
.import_function("SetBounds",
144 boost::bind(&impl::setBounds
, this, _1
));
145 script
.import_function("ResetTransform",
146 boost::bind(&impl::resetTransform
, this, _1
));
147 script
.import_function("Translate",
148 boost::bind(&impl::translate
, this, _1
));
149 script
.import_function("Scale",
150 boost::bind(&impl::scale
, this, _1
));
151 script
.import_function("Rotate",
152 boost::bind(&impl::rotate
, this, _1
));
153 script
.import_function("SetTexture",
154 boost::bind(&impl::setTexture
, this, _1
));
155 script
.import_function("DrawTilemap",
156 boost::bind(&impl::drawTilemap
, this, _1
));
157 script
.import_function("DrawTile",
158 boost::bind(&impl::drawTile
, this, _1
));
161 settings
.get("detail", detail
);
162 script
.globals().set_field("detail", detail
);
164 script
.globals().set_field("LOW", 1);
165 script
.globals().set_field("MEDIUM", 2);
166 script
.globals().set_field("HIGH", 3);
168 script
.globals().set_field("X", X
);
169 script
.globals().set_field("Y", Y
);
170 script
.globals().set_field("Z", Z
);
172 script
.globals().set_field("LEFT", Quad::LEFT
);
173 script
.globals().set_field("RIGHT", Quad::RIGHT
);
174 script
.globals().set_field("TOP", Quad::TOP
);
178 moof::script::status
load(moof::settings
& settings
, moof::script
& script
)
180 std::string path
= moof::resource::find_file("scenes/"+name(), "lua");
183 script
.push("the scene file could not be found");
184 return moof::script::file_error
;
187 importSceneBindings(settings
, script
);
188 return script
.do_file(path
);
192 static int loadBox(moof::script
& script
, moof::aabb3
& aabb
)
194 script
[1].require_table();
195 script
[2].require_table();
197 script
[1].push_field(1).get(aabb
.min
[0]);
198 script
[1].push_field(2).get(aabb
.min
[1]);
199 script
[1].push_field(3).get(aabb
.min
[2]);
200 script
[2].push_field(1).get(aabb
.max
[0]);
201 script
[2].push_field(2).get(aabb
.max
[1]);
202 script
[2].push_field(3).get(aabb
.max
[2]);
207 int setBounds(moof::script
& script
)
209 int ret
= 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
)
268 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 script
[1].require_string().get(mTexture
);
285 int drawTilemap(moof::script
& script
)
287 moof::script::slot table
= script
[1].require_table();
290 table
.get(width
, "width");
292 int nTiles
= table
.length();
293 if (nTiles
% width
!= 0)
295 table
.raise("invalid number of tiles");
298 if (width
== 0) table
.raise("width field must not be zero");
299 int height
= nTiles
/ width
;
301 moof::vector3 vertices
[height
+1][width
+1];
303 // the indices are stored upside-down in the scene file so that
304 // they are easier to edit as text, so we'll need to load them last
307 // do first row and first column of vertices
309 for (int w
= 0; w
<= width
; ++w
)
311 vertices
[height
][w
] = moof::demote(mTransform
*
312 moof::vector4(w
, height
, 0.0, 1.0));
314 for (int h
= 0; h
< height
; ++h
)
316 vertices
[h
][0] = moof::demote(mTransform
*
317 moof::vector4(0.0, h
, 0.0, 1.0));
321 for (int h
= height
- 1; h
>= 0; --h
)
323 for (int w
= 0; w
< width
; ++w
, ++i
)
331 vertices
[h
][wPlus1
] = moof::demote(mTransform
*
332 moof::vector4(wPlus1
, h
, 0.0, 1.0));
334 if (index
== moof::image::no_tile
) continue;
336 const moof::vector3
* corners
[4] = {
338 &vertices
[h
][wPlus1
],
339 &vertices
[hPlus1
][wPlus1
],
343 Quad
* quad
= new Quad(corners
, mTexture
, index
);
344 //quad->setSurface(surface);
346 boost::shared_ptr
<Quad
> quadPtr(quad
);
347 mObjects
.push_back(quadPtr
);
351 Quad::Surface surface
= Quad::NONE
;
352 table
.get(surface
, "surface");
354 if (surface
!= Quad::NONE
)
356 // need a 2d line for collisions
357 // assuming the camera always looks directly to -z when the
358 // scene is built, simply demoting the vector again should
359 // project the points to the xy-plane
361 moof::vector2 bl
= moof::demote(vertices
[0][0]);
362 moof::vector2 tr
= moof::demote(vertices
[height
][width
]);
364 mLines
.push_back(moof::line
<2>(bl
, tr
));
370 int drawTile(moof::script
& script
)
372 moof::script::slot param
= script
[1];
373 moof::script::slot top
= script
[-1];
377 bool blending
= false;
380 if (param
.is_table())
383 param
.get(width
, "u_scale");
384 param
.get(blending
, "blend");
385 param
.get(fog
, "fog");
387 else if (param
.is_number())
392 moof::vector3 vertices
[2][width
+1];
395 moof::scalar increment
= SCALAR(1.0) / moof::scalar(width
);
397 for (int h
= 0; h
<= 1; ++h
)
400 for (int w
= 0; w
<= width
; ++w
, xf
+= increment
)
402 vertices
[h
][w
] = moof::demote(mTransform
*
403 moof::vector4(xf
, moof::scalar(h
), 0.0, 1.0));
407 for (int w
= 0; w
< width
; ++w
)
411 const moof::vector3
* corners
[4] = {
413 &vertices
[0][wPlus1
],
414 &vertices
[1][wPlus1
],
418 Quad
* quad
= new Quad(corners
, mTexture
, index
);
419 quad
->setBlending(blending
);
422 boost::shared_ptr
<Quad
> quadPtr(quad
);
423 mObjects
.push_back(quadPtr
);
431 Scene::Scene(const std::string
& name
) :
433 impl_(Scene::impl::instance(name
)) {}
436 moof::script::status
Scene::load(moof::settings
& settings
, moof::script
& script
)
439 return impl_
->load(settings
, script
);
443 void Scene::draw(moof::scalar alpha
) const
445 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
446 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
448 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
453 impl_
->mBounds
.draw();
456 void Scene::draw_if_visible(moof::scalar alpha
,
457 const moof::frustum
& frustum
) const
459 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
460 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
462 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
464 (*it
)->draw_if_visible(alpha
, frustum
);
467 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
468 std::list
< moof::line
<2> >::const_iterator lit
;
470 for (lit
= lines
.begin(); lit
!= lines
.end(); ++lit
)
475 impl_
->mBounds
.draw();
479 bool Scene::castRay(const moof::ray
<2>& ray
,
480 std::list
<moof::ray
<2>::contact
>& hits
) const
482 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
483 std::list
< moof::line
<2> >::const_iterator it
;
485 for (it
= lines
.begin(); it
!= lines
.end(); ++it
)
487 moof::ray
<2>::contact hit
;
488 moof::scalar d
= (*it
).intersect_ray(ray
, hit
);
497 return !hits
.empty();
501 bool Scene::checkForCollision(Character
& character
)
505 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
506 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
509 moof::sphere
<3> sphere
= character
.sphere();
511 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
513 impl::Quad::Surface type
= (*it
)->getSurface();
514 if (type
== impl::Quad::NONE
) continue;
516 if (moof::checkCollision(sphere
, (*it
)->sphere()))
520 moof::vector2
impulse(0.0, 0.0);
521 moof::vector2 p
= character
.state().momentum
;
523 moof::state2 state
= character
.state(1.0);
524 sphere
= character
.sphere();
525 moof::scalar alpha
= 1.0;
526 while (moof::checkCollision(sphere
, (*it
)->sphere()))
529 state
= character
.state(alpha
);
532 character
.setPosition(state
.position
);
536 //case impl::Quad::TOP:
537 //if (p[1] < 0.0) impulse[1] = -p[1];
539 //case impl::Quad::LEFT:
540 //if (p[0] > 0.0) impulse[0] = 1.5*-p[0];
542 //case impl::Quad::RIGHT:
543 //if (p[0] < 0.0) impulse[0] = 1.5*-p[0];
547 //character.addImpulse(impulse);
553 moof::log_info
<< "collisions: " << collisions
<< std::endl
;
This page took 0.057731 seconds and 4 git commands to generate.