home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5164 / miletos.7z / camera.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2011-04-02  |  3.9 KB  |  158 lines

  1. #define __MILETOS_CAMERA_CPP__
  2.  
  3. //
  4. // Libmiletos
  5. //
  6. // Copyright (C) Lauris Kaplinski 2010
  7. //
  8.  
  9. #include <elea/line.h>
  10.  
  11. #include <sehle/engine.h>
  12. #include <sehle/graph.h>
  13. #include <sehle/renderable.h>
  14. #include <sehle/commonmaterials.h>
  15.  
  16. #include "xml/base.h"
  17. #include "sphere.h"
  18.  
  19. #include "camera.h"
  20.  
  21. namespace Miletos {
  22.  
  23. Camera::Camera (void)
  24. : Item(0), distance(3), focus(0.048f), mode(PERSPECTIVE)
  25. {
  26. }
  27.  
  28. static Object *
  29. camera_factory (void)
  30. {
  31.     return new Camera();
  32. }
  33.  
  34. const Object::Type *
  35. Camera::objectType (void)
  36. {
  37.     return type ();
  38. }
  39.  
  40. const Object::Type *
  41. Camera::type (void)
  42. {
  43.     static Type *mytype = NULL;
  44.     static const Attribute attrs[] = {
  45.         { "distance", NULL, 0 },
  46.         { "focus", NULL, 0 },
  47.         { "mode", "perspective", 0 }
  48.     };
  49.     if (!mytype) mytype = new Type(Item::type (), "Camera", "camera", camera_factory, sizeof (attrs) / sizeof (attrs[0]), attrs);
  50.     return mytype;
  51. }
  52.  
  53. void
  54. Camera::build (Thera::Node *pnode, Document *doc, BuildCtx *ctx)
  55. {
  56.     Item::build (pnode, doc, ctx);
  57.     buildAllAttributes (type (), ctx);
  58. }
  59.  
  60. void
  61. Camera::set (const char *attrid, const char *val)
  62. {
  63.     if (!strcmp (attrid, "distance")) {
  64.         if (!XML::parseNumber (&distance, val)) distance = 3;
  65.     } else if (!strcmp (attrid, "focus")) {
  66.         if (!XML::parseNumber (&focus, val)) focus = 0.048f;
  67.     } else if (!strcmp (attrid, "mode")) {
  68.         if (val && !strcmp (val, "isometric")) {
  69.             mode = ISOMETRIC;
  70.         } else {
  71.             mode = PERSPECTIVE;
  72.         }
  73.     } else {
  74.         Item::set (attrid, val);
  75.     }
  76. }
  77.  
  78. void
  79. Camera::write (const char *attrid)
  80. {
  81.     char c[256];
  82.     if (!strcmp (attrid, "distance")) {
  83.         XML::writeNumber (c, 64, distance);
  84.         node->setAttribute (attrid, c);
  85.     } else if (!strcmp (attrid, "focus")) {
  86.         XML::writeNumber (c, 64, focus);
  87.         node->setAttribute (attrid, c);
  88.     } else if (!strcmp (attrid, "mode")) {
  89.         node->setAttribute (attrid, (mode == ISOMETRIC) ? "isometric" : "perspective");
  90.     } else {
  91.         Item::write (attrid);
  92.     }
  93. }
  94.  
  95. static const float radius = 0.1f;
  96.  
  97. Sehle::Renderable *
  98. Camera::show (Sehle::Graph *pgraph, Sehle::u32 contextmask)
  99. {
  100.     // Create mesh
  101.     Sehle::StaticMesh *mesh = new Sehle::StaticMesh(graph, contextmask);
  102.  
  103.     int nvertices;
  104.     int nindices;
  105.     Sphere::generateMesh (NULL, 0, NULL, 0, NULL, 0, NULL, radius, 3, 1, nvertices, nindices);
  106.     if (!mesh->vbuffer) mesh->vbuffer = mesh->graph->engine->getVertexBuffer (NULL);
  107.     mesh->vbuffer->setUp (nvertices, 8);
  108.     mesh->vbuffer->setOffset (Sehle::VertexBuffer::COORDINATES, 0);
  109.     mesh->vbuffer->setOffset (Sehle::VertexBuffer::NORMALS, 3);
  110.     mesh->vbuffer->setOffset (Sehle::VertexBuffer::TEXCOORDS, 6);
  111.     Sehle::f32 *attributes = mesh->vbuffer->map (Sehle::VertexBuffer::WRITE);
  112.     if (!mesh->ibuffer) mesh->ibuffer = mesh->graph->engine->getIndexBuffer (NULL);
  113.     mesh->ibuffer->resize (nindices);
  114.     Sehle::u32 *indices = mesh->ibuffer->map (Sehle::IndexBuffer::WRITE);
  115.     Sphere::generateMesh (attributes, mesh->vbuffer->stride * sizeof (Sehle::f32),
  116.         attributes + 3, mesh->vbuffer->stride * sizeof (Sehle::f32),
  117.         attributes + 6, mesh->vbuffer->stride * sizeof (Sehle::f32),
  118.         indices, radius, 3, 1, nvertices, nindices);
  119.     mesh->vbuffer->unMap ();
  120.     mesh->ibuffer->unMap ();
  121.  
  122.     mesh->resizeMaterials (1);
  123.     mesh->setMaterial (0, Sehle::WireMaterial::newWireMaterial (mesh->graph->engine, NULL));
  124.     // mesh->setMaterial (0, Sehle::ColorMaterial::newColorMaterial (mesh->graph->engine, NULL));
  125.     mesh->resizeFragments (1);
  126.     mesh->frags[0].first = 0;
  127.     mesh->frags[0].nindices = nindices;
  128.     mesh->frags[0].matidx = 0;
  129.  
  130.     return mesh;
  131. }
  132.  
  133. Item *
  134. Camera::trace (const Elea::Line3f *wray, unsigned int mask, float *distance)
  135. {
  136.     Elea::Cuboid3f bbox(-radius, -radius, -radius, radius, radius, radius);
  137.     Elea::Line3f rl = _w2i.transform (*wray);
  138.  
  139.     // i2w.transformInPlace (bbox);
  140.     float p0, p1;
  141.     if (bbox.getIntersection (rl, p0, p1) && (p0 > 0)) {
  142.         *distance = p0;
  143.         return this;
  144.     }
  145.  
  146.     return NULL;
  147. }
  148.  
  149. void
  150. Camera::setPosition (const Elea::Matrix4x4f *pv2w, float pdistance, float pfocus, int mode)
  151. {
  152.     distance = pdistance;
  153.     focus = pfocus;
  154.     this->setI2W (pv2w);
  155. }
  156.  
  157. } // Namespace Miletos
  158.