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
1.5.6