InstancedShape.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   InstancedShape.cpp
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Fall 2008
00006    
00007    @brief
00008       Acts as a proxy for a shape which has been instanced
00009    <!-------------------------------------------------------------------->**/
00010 
00011 #include "InstancedShape.h"
00012 #include <SurfacePoint.h>
00013 #include <Material.h>
00014 
00015 void InstancedShape::init() {
00016    // prevent infinite recursion if by some chance, an shape is self-instancing
00017    Shape *instancee = m_instancee;
00018    m_instancee = NULL;
00019    
00020    // ensure instancee has already been initted
00021    instancee->init();
00022    m_instancee = instancee;
00023    
00024    // setup AABB and transforms
00025    if (m_instancee->isTransformable()) {
00026       Transformable *trans = dynamic_cast<Transformable*>(m_instancee);
00027       m_objSpaceAABB    = trans->getObjSpaceAABB();
00028       
00029       // instanced shape's transform effectively 'undoes' the instancee's 
00030       // transform in addition to applying its own, without the instancee 
00031       // even knowing
00032       m_transToWorld    = m_transToWorld * trans->getTransToWorldInv();
00033       m_transToWorldInv = trans->getTransToWorld() * m_transToWorldInv;
00034    } else {
00035       m_objSpaceAABB = m_instancee->getAABB();
00036    }
00037    
00038    Transformable::init();
00039 }
00040 
00041 real_t InstancedShape::getIntersection(const Ray &ray, SurfacePoint &pt) {
00042    Point3  P;
00043    Vector3 D;
00044    _transformRayWorldToObj(ray, P, D);
00045    
00046    const real_t t = m_instancee->getIntersection(Ray(P, D), pt);
00047    
00048    if (Ray::isValid(t))
00049       pt.shape = this;
00050    
00051    return t;
00052 }
00053 
00054 bool InstancedShape::intersects(const Ray &ray, real_t tMax) {
00055    Point3  P;
00056    Vector3 D;
00057    _transformRayWorldToObj(ray, P, D);
00058    
00059    return m_instancee->intersects(Ray(P, D), tMax);
00060 }
00061 
00062 bool InstancedShape::hasNormal() const {
00063    return m_instancee->hasNormal();
00064 }
00065 
00066 void InstancedShape::preview() {
00067    Transformable::preview();
00068    
00069    m_instancee->preview();
00070 }
00071 
00072 void InstancedShape::getRandomPoint(SurfacePoint &pt) {
00073    m_instancee->getRandomPoint(pt);
00074    
00075    pt.shape = this;
00076 }
00077 
00078 Point3 InstancedShape::getPosition(const UV &uv) {
00079    const Point3 &position = m_instancee->getPosition(uv);
00080    
00081    return m_transToWorld * position;
00082 }
00083 
00084 real_t InstancedShape::_getSurfaceArea() {
00085    // TODO: this is probably incorrect for world-space surface area!!!
00086    
00087    return m_instancee->_getSurfaceArea();
00088 }
00089 
00090 void InstancedShape::initSurfacePoint(SurfacePoint &pt) const {
00091    const Point3 &position = pt.position;
00092    
00093    pt.position = m_transToWorldInv * position;
00094    m_instancee->initSurfacePoint(pt);
00095    pt.position = position;
00096    
00097    // TODO: prevent surface point from being initted twice
00098    ASSERT(m_material);
00099    m_material->initSurfacePoint(pt);
00100 }
00101 
00102 void InstancedShape::_getUV(SurfacePoint &pt) const {
00103    const Point3 &position = pt.position;
00104    
00105    pt.position = m_transToWorldInv * position;
00106    m_instancee->_getUV(pt);
00107    pt.position = position;
00108 }
00109 
00110 void InstancedShape::_getGeometricNormal(SurfacePoint &pt) const {
00111    const Point3 &position = pt.position;
00112    
00113    pt.position = m_transToWorldInv * position;
00114    m_instancee->_getGeometricNormal(pt);
00115    pt.position = position;
00116    
00117    _transformVector3ObjToWorld(pt.normalG, pt.normalG);
00118 }
00119 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6