home *** CD-ROM | disk | FTP | other *** search
- #define __MILETOS_CAMERA_CPP__
-
- //
- // Libmiletos
- //
- // Copyright (C) Lauris Kaplinski 2010
- //
-
- #include <elea/line.h>
-
- #include <sehle/engine.h>
- #include <sehle/graph.h>
- #include <sehle/renderable.h>
- #include <sehle/commonmaterials.h>
-
- #include "xml/base.h"
- #include "sphere.h"
-
- #include "camera.h"
-
- namespace Miletos {
-
- Camera::Camera (void)
- : Item(0), distance(3), focus(0.048f), mode(PERSPECTIVE)
- {
- }
-
- static Object *
- camera_factory (void)
- {
- return new Camera();
- }
-
- const Object::Type *
- Camera::objectType (void)
- {
- return type ();
- }
-
- const Object::Type *
- Camera::type (void)
- {
- static Type *mytype = NULL;
- static const Attribute attrs[] = {
- { "distance", NULL, 0 },
- { "focus", NULL, 0 },
- { "mode", "perspective", 0 }
- };
- if (!mytype) mytype = new Type(Item::type (), "Camera", "camera", camera_factory, sizeof (attrs) / sizeof (attrs[0]), attrs);
- return mytype;
- }
-
- void
- Camera::build (Thera::Node *pnode, Document *doc, BuildCtx *ctx)
- {
- Item::build (pnode, doc, ctx);
- buildAllAttributes (type (), ctx);
- }
-
- void
- Camera::set (const char *attrid, const char *val)
- {
- if (!strcmp (attrid, "distance")) {
- if (!XML::parseNumber (&distance, val)) distance = 3;
- } else if (!strcmp (attrid, "focus")) {
- if (!XML::parseNumber (&focus, val)) focus = 0.048f;
- } else if (!strcmp (attrid, "mode")) {
- if (val && !strcmp (val, "isometric")) {
- mode = ISOMETRIC;
- } else {
- mode = PERSPECTIVE;
- }
- } else {
- Item::set (attrid, val);
- }
- }
-
- void
- Camera::write (const char *attrid)
- {
- char c[256];
- if (!strcmp (attrid, "distance")) {
- XML::writeNumber (c, 64, distance);
- node->setAttribute (attrid, c);
- } else if (!strcmp (attrid, "focus")) {
- XML::writeNumber (c, 64, focus);
- node->setAttribute (attrid, c);
- } else if (!strcmp (attrid, "mode")) {
- node->setAttribute (attrid, (mode == ISOMETRIC) ? "isometric" : "perspective");
- } else {
- Item::write (attrid);
- }
- }
-
- static const float radius = 0.1f;
-
- Sehle::Renderable *
- Camera::show (Sehle::Graph *pgraph, Sehle::u32 contextmask)
- {
- // Create mesh
- Sehle::StaticMesh *mesh = new Sehle::StaticMesh(graph, contextmask);
-
- int nvertices;
- int nindices;
- Sphere::generateMesh (NULL, 0, NULL, 0, NULL, 0, NULL, radius, 3, 1, nvertices, nindices);
- if (!mesh->vbuffer) mesh->vbuffer = mesh->graph->engine->getVertexBuffer (NULL);
- mesh->vbuffer->setUp (nvertices, 8);
- mesh->vbuffer->setOffset (Sehle::VertexBuffer::COORDINATES, 0);
- mesh->vbuffer->setOffset (Sehle::VertexBuffer::NORMALS, 3);
- mesh->vbuffer->setOffset (Sehle::VertexBuffer::TEXCOORDS, 6);
- Sehle::f32 *attributes = mesh->vbuffer->map (Sehle::VertexBuffer::WRITE);
- if (!mesh->ibuffer) mesh->ibuffer = mesh->graph->engine->getIndexBuffer (NULL);
- mesh->ibuffer->resize (nindices);
- Sehle::u32 *indices = mesh->ibuffer->map (Sehle::IndexBuffer::WRITE);
- Sphere::generateMesh (attributes, mesh->vbuffer->stride * sizeof (Sehle::f32),
- attributes + 3, mesh->vbuffer->stride * sizeof (Sehle::f32),
- attributes + 6, mesh->vbuffer->stride * sizeof (Sehle::f32),
- indices, radius, 3, 1, nvertices, nindices);
- mesh->vbuffer->unMap ();
- mesh->ibuffer->unMap ();
-
- mesh->resizeMaterials (1);
- mesh->setMaterial (0, Sehle::WireMaterial::newWireMaterial (mesh->graph->engine, NULL));
- // mesh->setMaterial (0, Sehle::ColorMaterial::newColorMaterial (mesh->graph->engine, NULL));
- mesh->resizeFragments (1);
- mesh->frags[0].first = 0;
- mesh->frags[0].nindices = nindices;
- mesh->frags[0].matidx = 0;
-
- return mesh;
- }
-
- Item *
- Camera::trace (const Elea::Line3f *wray, unsigned int mask, float *distance)
- {
- Elea::Cuboid3f bbox(-radius, -radius, -radius, radius, radius, radius);
- Elea::Line3f rl = _w2i.transform (*wray);
-
- // i2w.transformInPlace (bbox);
- float p0, p1;
- if (bbox.getIntersection (rl, p0, p1) && (p0 > 0)) {
- *distance = p0;
- return this;
- }
-
- return NULL;
- }
-
- void
- Camera::setPosition (const Elea::Matrix4x4f *pv2w, float pdistance, float pfocus, int mode)
- {
- distance = pdistance;
- focus = pfocus;
- this->setI2W (pv2w);
- }
-
- } // Namespace Miletos
-