]>
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/texture.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
,
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 if (!mTilemap
.tile_coordinates(tileIndex
, mTexCoords
))
60 moof::log_warning
<< "no index " << tileIndex
<<
61 " in texture " << texture
<< std::endl
;
63 mTexCoords
[0] = mTexCoords
[1] =
64 mTexCoords
[3] = mTexCoords
[6] = 0.0;
65 mTexCoords
[2] = mTexCoords
[4] =
66 mTexCoords
[5] = mTexCoords
[7] = 1.0;
69 aabb_
.enclose_vertices(mVertices
, 4);
70 sphere_
.point
= aabb_
.center();
71 sphere_
.radius
= (aabb_
.min
- sphere_
.point
).length();
74 void setBlending(bool blending
)
84 void setSurface(Surface type
)
89 Surface
getSurface() const
94 void draw(moof::scalar alpha
= 0.0) const
99 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
105 glFogi(GL_FOG_MODE
, GL_LINEAR
);
108 //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
111 glVertexPointer(3, GL_SCALAR
, 0, mVertices
[0].data());
112 glTexCoordPointer(2, GL_SCALAR
, 0, mTexCoords
);
114 glDrawArrays(GL_TRIANGLE_FAN
, 0, 4);
120 bool is_visible(const moof::frustum
& frustum
) const
122 return sphere_
.is_visible(frustum
);
126 moof::vector3 mVertices
[4];
127 moof::scalar mTexCoords
[8];
129 moof::texture mTilemap
;
138 moof::matrix4 mTransform
;
139 std::string mTexture
;
141 std::list
< boost::shared_ptr
<impl::Quad
> > mObjects
;
142 std::list
<moof::line2
> mLines
;
144 moof::aabb
<3> mBounds
;
155 void init(const std::string
& name
) {}
158 void importSceneBindings(moof::settings
& settings
, moof::script
& script
)
160 script
.import_function("SetBounds",
161 boost::bind(&impl::setBounds
, this, _1
));
162 script
.import_function("ResetTransform",
163 boost::bind(&impl::resetTransform
, this, _1
));
164 script
.import_function("Translate",
165 boost::bind(&impl::translate
, this, _1
));
166 script
.import_function("Scale",
167 boost::bind(&impl::scale
, this, _1
));
168 script
.import_function("Rotate",
169 boost::bind(&impl::rotate
, this, _1
));
170 script
.import_function("SetTexture",
171 boost::bind(&impl::setTexture
, this, _1
));
172 script
.import_function("DrawTilemap",
173 boost::bind(&impl::drawTilemap
, this, _1
));
174 script
.import_function("DrawTile",
175 boost::bind(&impl::drawTile
, this, _1
));
178 settings
.get("detail", detail
);
179 script
.globals().set_field("detail", detail
);
181 script
.globals().set_field("LOW", 1);
182 script
.globals().set_field("MEDIUM", 2);
183 script
.globals().set_field("HIGH", 3);
185 script
.globals().set_field("X", X
);
186 script
.globals().set_field("Y", Y
);
187 script
.globals().set_field("Z", Z
);
189 script
.globals().set_field("LEFT", Quad::LEFT
);
190 script
.globals().set_field("RIGHT", Quad::RIGHT
);
191 script
.globals().set_field("TOP", Quad::TOP
);
195 moof::script::status
load(moof::settings
& settings
, moof::script
& script
)
197 std::string
path(name());
198 if (!resource::find(path
))
200 script
.push("the scene file could not be found");
201 return moof::script::file_error
;
204 importSceneBindings(settings
, script
);
205 return script
.do_file(path
);
209 static int loadBox(moof::script
& script
, moof::aabb3
& aabb
)
211 script
[1].require_table();
212 script
[2].require_table();
214 script
[1].push_field(1).get(aabb
.min
[0]);
215 script
[1].push_field(2).get(aabb
.min
[1]);
216 script
[1].push_field(3).get(aabb
.min
[2]);
217 script
[2].push_field(1).get(aabb
.max
[0]);
218 script
[2].push_field(2).get(aabb
.max
[1]);
219 script
[2].push_field(3).get(aabb
.max
[2]);
224 int setBounds(moof::script
& script
)
226 int ret
= loadBox(script
, mBounds
);
230 int resetTransform(moof::script
& script
)
232 mTransform
.identity();
236 int translate(moof::script
& script
)
239 script
[1].require_number().get(vec
[0]);
240 script
[2].require_number().get(vec
[1]);
241 script
[3].require_number().get(vec
[2]);
243 moof::matrix4 translation
;
244 moof::matrix_translation(translation
, vec
);
245 mTransform
= translation
* mTransform
;
250 int scale(moof::script
& script
)
252 int size
= script
.stack_size();
256 moof::scalar value
= 1.0;
257 script
[1].require_number().get(value
);
259 moof::matrix4 scaling
;
260 moof::matrix_uniform_scale(scaling
, value
);
261 mTransform
= scaling
* mTransform
;
266 script
[1].require_number().get(vec
[0]);
267 script
[2].require_number().get(vec
[1]);
268 script
[3].require_number().get(vec
[2]);
270 moof::matrix4 scaling
;
271 moof::matrix_scale(scaling
, vec
);
272 mTransform
= scaling
* mTransform
;
276 script
.top().raise("wrong number of arguments");
282 int rotate(moof::script
& script
)
285 script
[1].require_number().get(index
);
288 script
[2].require_number().get(value
);
290 moof::matrix_rotate_about_world_axis(mTransform
, index
,
296 int setTexture(moof::script
& script
)
298 script
[1].require_string().get(mTexture
);
302 int drawTilemap(moof::script
& script
)
304 moof::script::slot table
= script
[1].require_table();
307 table
.get(width
, "width");
309 int nTiles
= table
.length();
310 if (nTiles
% width
!= 0)
312 table
.raise("invalid number of tiles");
315 if (width
== 0) table
.raise("width field must not be zero");
316 int height
= nTiles
/ width
;
318 moof::vector3 vertices
[height
+1][width
+1];
320 // the indices are stored upside-down in the scene file so that
321 // they are easier to edit as text, so we'll need to load them last
324 // do first row and first column of vertices
326 for (int w
= 0; w
<= width
; ++w
)
328 vertices
[height
][w
] = moof::demote(mTransform
*
329 moof::vector4(w
, height
, 0.0, 1.0));
331 for (int h
= 0; h
< height
; ++h
)
333 vertices
[h
][0] = moof::demote(mTransform
*
334 moof::vector4(0.0, h
, 0.0, 1.0));
338 for (int h
= height
- 1; h
>= 0; --h
)
340 for (int w
= 0; w
< width
; ++w
, ++i
)
348 vertices
[h
][wPlus1
] = moof::demote(mTransform
*
349 moof::vector4(wPlus1
, h
, 0.0, 1.0));
351 if (index
== moof::texture::no_tile
) continue;
353 const moof::vector3
* corners
[4] = {
355 &vertices
[h
][wPlus1
],
356 &vertices
[hPlus1
][wPlus1
],
360 Quad
* quad
= new Quad(corners
, mTexture
, index
);
361 //quad->setSurface(surface);
363 boost::shared_ptr
<Quad
> quadPtr(quad
);
364 mObjects
.push_back(quadPtr
);
368 Quad::Surface surface
= Quad::NONE
;
369 table
.get(surface
, "surface");
371 if (surface
!= Quad::NONE
)
373 // need a 2d line for collisions
374 // assuming the camera always looks directly to -z when the
375 // scene is built, simply demoting the vector again should
376 // project the points to the xy-plane
378 moof::vector2 bl
= moof::demote(vertices
[0][0]);
379 moof::vector2 tr
= moof::demote(vertices
[height
][width
]);
381 mLines
.push_back(moof::line
<2>(bl
, tr
));
387 int drawTile(moof::script
& script
)
389 moof::script::slot param
= script
[1];
390 moof::script::slot top
= script
[-1];
394 bool blending
= false;
397 if (param
.is_table())
400 param
.get(width
, "u_scale");
401 param
.get(blending
, "blend");
402 param
.get(fog
, "fog");
404 else if (param
.is_number())
409 moof::vector3 vertices
[2][width
+1];
412 moof::scalar increment
= SCALAR(1.0) / moof::scalar(width
);
414 for (int h
= 0; h
<= 1; ++h
)
417 for (int w
= 0; w
<= width
; ++w
, xf
+= increment
)
419 vertices
[h
][w
] = moof::demote(mTransform
*
420 moof::vector4(xf
, moof::scalar(h
), 0.0, 1.0));
424 for (int w
= 0; w
< width
; ++w
)
428 const moof::vector3
* corners
[4] = {
430 &vertices
[0][wPlus1
],
431 &vertices
[1][wPlus1
],
435 Quad
* quad
= new Quad(corners
, mTexture
, index
);
436 quad
->setBlending(blending
);
439 boost::shared_ptr
<Quad
> quadPtr(quad
);
440 mObjects
.push_back(quadPtr
);
448 Scene::Scene(const std::string
& name
) :
450 impl_(Scene::impl::instance(name
)) {}
453 moof::script::status
Scene::load(moof::settings
& settings
, moof::script
& script
)
456 return impl_
->load(settings
, script
);
460 void Scene::draw(moof::scalar alpha
) const
462 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
463 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
465 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
470 impl_
->mBounds
.draw();
473 void Scene::draw_if_visible(moof::scalar alpha
,
474 const moof::frustum
& frustum
) const
476 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
477 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
479 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
481 (*it
)->draw_if_visible(alpha
, frustum
);
484 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
485 std::list
< moof::line
<2> >::const_iterator lit
;
487 for (lit
= lines
.begin(); lit
!= lines
.end(); ++lit
)
492 impl_
->mBounds
.draw();
496 bool Scene::castRay(const moof::ray
<2>& ray
,
497 std::list
<moof::ray
<2>::contact
>& hits
) const
499 std::list
< moof::line
<2> >& lines
= impl_
->mLines
;
500 std::list
< moof::line
<2> >::const_iterator it
;
502 for (it
= lines
.begin(); it
!= lines
.end(); ++it
)
504 moof::ray
<2>::contact hit
;
505 moof::scalar d
= (*it
).intersect_ray(ray
, hit
);
514 return !hits
.empty();
518 bool Scene::checkForCollision(Character
& character
)
522 std::list
< boost::shared_ptr
<impl::Quad
> >& objects
= impl_
->mObjects
;
523 std::list
< boost::shared_ptr
<impl::Quad
> >::const_iterator it
;
526 moof::sphere
<3> sphere
= character
.sphere();
528 for (it
= objects
.begin(); it
!= objects
.end(); ++it
)
530 impl::Quad::Surface type
= (*it
)->getSurface();
531 if (type
== impl::Quad::NONE
) continue;
533 if (moof::checkCollision(sphere
, (*it
)->sphere()))
537 moof::vector2
impulse(0.0, 0.0);
538 moof::vector2 p
= character
.state().momentum
;
540 moof::state2 state
= character
.state(1.0);
541 sphere
= character
.sphere();
542 moof::scalar alpha
= 1.0;
543 while (moof::checkCollision(sphere
, (*it
)->sphere()))
546 state
= character
.state(alpha
);
549 character
.setPosition(state
.position
);
553 //case impl::Quad::TOP:
554 //if (p[1] < 0.0) impulse[1] = -p[1];
556 //case impl::Quad::LEFT:
557 //if (p[0] > 0.0) impulse[0] = 1.5*-p[0];
559 //case impl::Quad::RIGHT:
560 //if (p[0] < 0.0) impulse[0] = 1.5*-p[0];
564 //character.addImpulse(impulse);
570 moof::log_info
<< "collisions: " << collisions
<< std::endl
;
This page took 0.062625 seconds and 5 git commands to generate.