]>
Dogcows Code - chaz/yoink/blob - src/Moof/Scene.cc
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 *******************************************************************************/
35 #include "Deserializer.hh"
38 #include "Mippleton.hh"
42 #include "Serializable.hh"
49 class Scene::SceneImpl
: public Mippleton
<SceneImpl
>
51 class Scenery
: public Entity
54 Scenery(const Matrix4
& transform
, const std::string
& textureName
) :
55 transformation(transform
),
59 Matrix4 transformation
;
66 class TilePanel
: public Scenery
69 TilePanel(const Matrix4
& transform
, const std::string
& textureName
,
70 SerializablePtr root
) :
71 Scenery(transform
, textureName
),
75 std::map
<std::string
,SerializablePtr
> rootObj
;
77 if (root
->get(rootObj
))
79 std::map
<std::string
,SerializablePtr
>::iterator it
;
81 if ((it
= rootObj
.find("width")) != rootObj
.end())
83 (*it
).second
->get(width
);
85 if ((it
= rootObj
.find("tiles")) != rootObj
.end())
87 std::vector
<SerializablePtr
> theTiles
;
89 if ((*it
).second
->get(theTiles
))
91 std::vector
<SerializablePtr
>::iterator jt
;
93 height
= theTiles
.size() / width
;
96 indices
.resize(height
);
98 for (h
= height
- 1, jt
= theTiles
.begin();
99 jt
!= theTiles
.end(); h
--)
101 std::vector
<Tilemap::Index
> row
;
103 for (w
= 0; w
< width
&& jt
!= theTiles
.end();
108 if ((*jt
)->get(index
))
110 row
.push_back(Tilemap::Index(index
));
121 void draw(Scalar alpha
) const
124 //std::cout << "transforming..." << std::endl;
125 //std::cout << transformation << std::endl;
126 glMultMatrix(transformation
.data());
128 glColor4f(1.0f
, 1.0f
, 1.0f
, 1.0f
);
134 for (y
= 0, yf
= 0.0; y
< height
; y
++, yf
+= 1.0)
136 for (x
= 0, xf
= 0.0; x
< width
; x
++, xf
+= 1.0)
140 Tilemap::Index index
= indices
[y
][x
];
142 if (image
.getTileCoords(index
, texCoords
))
144 glBegin(GL_TRIANGLE_FAN
);
145 glTexCoord2f(texCoords
[0], texCoords
[1]);
147 glTexCoord2f(texCoords
[2], texCoords
[3]);
148 glVertex2f(xf
+1.0, yf
);
149 glTexCoord2f(texCoords
[4], texCoords
[5]);
150 glVertex2f(xf
+1.0, yf
+1.0);
151 glTexCoord2f(texCoords
[6], texCoords
[7]);
152 glVertex2f(xf
, yf
+1.0);
161 bool isVisible(const Camera
& cam
)
168 std::vector
<std::vector
<Tilemap::Index
> > indices
;
171 class Billboard
: public Scenery
174 Billboard(const Matrix4
& transform
, const std::string
& textureName
,
175 SerializablePtr root
) :
176 Scenery(transform
, textureName
),
180 std::map
<std::string
,SerializablePtr
> rootObj
;
182 if (root
->get(rootObj
))
184 std::map
<std::string
,SerializablePtr
>::iterator it
;
186 if ((it
= rootObj
.find("tile")) != rootObj
.end())
189 if ((*it
).second
->get(value
))
191 index
= Tilemap::Index(value
);
194 if ((it
= rootObj
.find("u_scale")) != rootObj
.end())
196 (*it
).second
->get(uScale
);
198 if ((it
= rootObj
.find("fog")) != rootObj
.end())
200 (*it
).second
->get(fog
);
202 if ((it
= rootObj
.find("blend")) != rootObj
.end())
204 (*it
).second
->get(blending
);
208 image
.getTileCoords(index
, texCoords
);
211 void draw(Scalar alpha
) const
214 glMultMatrix(transformation
.data());
219 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
221 /*if (fog) glEnable(GL_FOG);*/
223 glColor4f(1.0f
, 1.0f
, 1.0f
, 1.0f
);
226 float increment
= 1.0f
/ float(uScale
);
230 for (x
= 0, xf
= 0.0f
; x
< uScale
; x
++, xf
+= increment
)
232 glBegin(GL_TRIANGLE_FAN
);
233 glTexCoord2f(texCoords
[0], texCoords
[1]);
234 glVertex2f(xf
, 0.0f
);
235 glTexCoord2f(texCoords
[2], texCoords
[3]);
236 glVertex2f(xf
+increment
, 0.0f
);
237 glTexCoord2f(texCoords
[4], texCoords
[5]);
238 glVertex2f(xf
+increment
, 1.0f
);
239 glTexCoord2f(texCoords
[6], texCoords
[7]);
240 glVertex2f(xf
, 1.0f
);
250 bool isVisible(const Camera
& cam
)
256 Tilemap::Index index
;
262 static bool loadBox(Aabb
& theBox
, SerializablePtr obj
)
264 std::vector
<SerializablePtr
> numbers
;
266 if (obj
->get(numbers
))
268 if (numbers
.size() == 6)
272 if (numbers
[0]->getNumber(num
))
274 theBox
.min
[0] = Scalar(num
);
276 if (numbers
[1]->getNumber(num
))
278 theBox
.min
[1] = Scalar(num
);
280 if (numbers
[2]->getNumber(num
))
282 theBox
.min
[2] = Scalar(num
);
284 if (numbers
[3]->getNumber(num
))
286 theBox
.max
[0] = Scalar(num
);
288 if (numbers
[4]->getNumber(num
))
290 theBox
.max
[1] = Scalar(num
);
292 if (numbers
[5]->getNumber(num
))
294 theBox
.max
[2] = Scalar(num
);
303 SceneImpl(const std::string
& name
) :
304 Mippleton
<SceneImpl
>(name
)
314 void loadInstructions(SerializablePtr root
)
316 std::vector
<SerializablePtr
> rootObj
;
318 if (root
->get(rootObj
))
320 std::vector
<SerializablePtr
>::iterator it
;
325 for (it
= rootObj
.begin(); it
!= rootObj
.end(); it
++)
327 std::string instruction
;
329 if ((*it
)->get(instruction
))
331 if (instruction
== "reset_transform")
333 transform
.identity();
335 else if (instruction
== "translate")
337 std::vector
<SerializablePtr
> values
;
340 if ((*it
)->get(values
))
344 for (size_t i
= 0; i
< values
.size(); i
++)
348 if (values
[i
]->getNumber(value
))
355 cml::matrix_translation(translation
, vec
);
356 transform
= translation
* transform
;
359 else if (instruction
== "scale")
361 std::vector
<SerializablePtr
> values
;
364 if ((*it
)->get(values
))
366 if (values
.size() == 1)
370 values
[0]->getNumber(value
);
373 cml::matrix_uniform_scale(scaling
, Scalar(value
));
374 transform
= scaling
* transform
;
376 else if (values
.size() == 3)
380 for (size_t i
= 0; i
< values
.size(); i
++)
384 if (values
[i
]->getNumber(value
))
391 cml::matrix_scale(scaling
, vec
);
392 transform
= scaling
* transform
;
396 else if (instruction
== "rotate")
398 std::vector
<SerializablePtr
> values
;
401 if ((*it
)->get(values
))
403 if (values
.size() == 2)
406 size_t axisIndex
= 0;
408 Vector3
vec(0.0, 0.0, 0.0);
410 if (values
[0]->get(axis
))
417 else if (axis
== "y")
422 else if (axis
== "z")
427 values
[1]->getNumber(value
);
430 cml::matrix_rotate_about_world_axis(transform
,
431 axisIndex
, Scalar(value
* cml::constantsd::rad_per_deg()));
435 else if (instruction
== "texture")
440 else if (instruction
== "tilemap")
443 TilePanel
* tilePanel
= new TilePanel(transform
, texture
,
445 boost::shared_ptr
<Scenery
> sceneItem(tilePanel
);
446 objects
.push_back(sceneItem
);
448 else if (instruction
== "billboard")
451 Billboard
* billboard
= new Billboard(transform
, texture
,
453 boost::shared_ptr
<Scenery
> sceneItem(billboard
);
454 objects
.push_back(sceneItem
);
464 std::string filePath
= Scene::getPathToResource(getName());
466 Deserializer
deserializer(filePath
, true);
468 SerializablePtr root
= deserializer
.deserialize();
472 std::map
<std::string
,SerializablePtr
> rootObj
;
474 if (root
->get(rootObj
))
476 std::map
<std::string
,SerializablePtr
>::iterator it
;
478 if ((it
= rootObj
.find("playfield_bounds")) != rootObj
.end())
480 loadBox(playfieldBounds
, (*it
).second
);
482 if ((it
= rootObj
.find("maximum_bounds")) != rootObj
.end())
484 loadBox(maximumBounds
, (*it
).second
);
486 if ((it
= rootObj
.find("instructions")) != rootObj
.end())
488 loadInstructions((*it
).second
);
493 std::cout
<< "playfield: " << playfieldBounds
.min
<< " ... " <<
494 playfieldBounds
.max
<< std::endl
;
498 void draw(Scalar alpha
)
500 SceneryVector::iterator it
;
502 for (it
= objects
.begin(); it
!= objects
.end(); it
++)
504 //std::cout << "draw object";
508 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
510 glBindTexture(GL_TEXTURE_2D
, 0);
511 glColor4f(0.0f
, 1.0f
, 0.0f
, 1.0f
);
512 playfieldBounds
.draw(0.0);
514 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
518 Aabb playfieldBounds
;
521 typedef std::vector
<boost::shared_ptr
<Scenery
> > SceneryVector
;
522 SceneryVector objects
;
526 Scene::Scene(const std::string
& name
) :
528 impl_(Scene::SceneImpl::retain(name
), &Scene::SceneImpl::release
) {}
531 void Scene::draw(Scalar alpha
) const
537 void Scene::refresh()
539 impl_
->objects
.clear();
540 impl_
->loadFromFile();
545 * Specialized search location for scene files. They can be found in the
546 * "scenes" subdirectory of any of the searched directories.
549 std::string
Scene::getPathToResource(const std::string
& name
)
551 return Resource::getPathToResource("scenes/" + name
+ ".json");
557 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.065523 seconds and 5 git commands to generate.