rename Python module from 'raytracer' to 'pyrit'
improve Python binding:
- new objects: Container, Octree, KdTree, Shape,
Pixmap, Sampler, DefaultSampler
- all shapes are now subclasses of Shape
- clean, remove redundant Getattr's
- Raytracer render method now just wraps C++ method
without doing any additional work
adjust all demos for changes in Python binding, remove PIL dependency
add demo_PIL.py as a example of pyrit + PIL usage
render_nff.py now either loads file given as a argument
or reads input from stdin otherwise
fix bug in pixmap float to char conversion
/*
* scene.cc: classes for objects in scene
*
* This file is part of Pyrit Ray Tracer.
*
* Copyright 2006, 2007, 2008 Radek Brich
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "scene.h"
void Camera::rotate(const Quaternion &q)
{
/*
//non-optimized
Quaternion res;
res = q * Quaternion(u) * conjugate(q);
u = res.toVector();
res = q * Quaternion(v) * conjugate(q);
v = res.toVector();
res = q * Quaternion(p) * conjugate(q);
p = res.toVector();
*/
// optimized
Float t2 = q.a*q.b;
Float t3 = q.a*q.c;
Float t4 = q.a*q.d;
Float t5 = -q.b*q.b;
Float t6 = q.b*q.c;
Float t7 = q.b*q.d;
Float t8 = -q.c*q.c;
Float t9 = q.c*q.d;
Float t10 = -q.d*q.d;
Float x,y,z;
x = 2*( (t8 + t10)*p.x + (t6 - t4)*p.y + (t3 + t7)*p.z ) + p.x;
y = 2*( (t4 + t6)*p.x + (t5 + t10)*p.y + (t9 - t2)*p.z ) + p.y;
z = 2*( (t7 - t3)*p.x + (t2 + t9)*p.y + (t5 + t8)*p.z ) + p.z;
p = Vector3(x,y,z);
x = 2*( (t8 + t10)*u.x + (t6 - t4)*u.y + (t3 + t7)*u.z ) + u.x;
y = 2*( (t4 + t6)*u.x + (t5 + t10)*u.y + (t9 - t2)*u.z ) + u.y;
z = 2*( (t7 - t3)*u.x + (t2 + t9)*u.y + (t5 + t8)*u.z ) + u.z;
u = Vector3(x,y,z);
x = 2*( (t8 + t10)*v.x + (t6 - t4)*v.y + (t3 + t7)*v.z ) + v.x;
y = 2*( (t4 + t6)*v.x + (t5 + t10)*v.y + (t9 - t2)*v.z ) + v.y;
z = 2*( (t7 - t3)*v.x + (t2 + t9)*v.y + (t5 + t8)*v.z ) + v.z;
v = Vector3(x,y,z);
p.normalize();
u.normalize();
v.normalize();
}
void Camera::move(const Float fw, const Float left, const Float up)
{
eye = eye + fw*p + left*u + up*v;
}
/* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */
bool BBox::intersect(const Ray &ray, Float &a, Float &b)
{
register Float tnear = -Inf;
register Float tfar = Inf;
register Float t1, t2;
for (int i = 0; i < 3; i++)
{
if (ray.dir[i] == 0) {
/* ray is parallel to these planes */
if (ray.o[i] < L[i] || ray.o[i] > H[i])
return false;
} else
{
/* compute the intersection distance of the planes */
t1 = (L[i] - ray.o[i]) / ray.dir[i];
t2 = (H[i] - ray.o[i]) / ray.dir[i];
if (t1 > t2)
swap(t1, t2);
if (t1 > tnear)
tnear = t1; /* want largest Tnear */
if (t2 < tfar)
tfar = t2; /* want smallest Tfar */
if (tnear > tfar || tfar < 0)
return false; /* box missed; box is behind ray */
}
}
a = tnear;
b = tfar;
return true;
}
// rewrite of BBox::intersect for ray packets
__m128 BBox::intersect_packet(const RayPacket &rays, __m128 &a, __m128 &b)
{
register __m128 tnear = mZero;
register __m128 tfar = mInf;
register __m128 t1, t2;
register __m128 mask = mAllSet;
for (int i = 0; i < 3; i++)
{
const __m128 mL = _mm_set_ps1(L[i]);
const __m128 mH = _mm_set_ps1(H[i]);
mask = _mm_and_ps(mask,
_mm_or_ps(
_mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)),
_mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH))
));
if (!_mm_movemask_ps(mask))
return mask;
/* compute the intersection distance of the planes */
t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]);
t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]);
__m128 t = _mm_min_ps(t1, t2);
t2 = _mm_max_ps(t1, t2);
t1 = t;
tnear = _mm_max_ps(tnear, t1); /* want largest Tnear */
tfar = _mm_min_ps(tfar, t2); /* want smallest Tfar */
mask = _mm_and_ps(mask,
_mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero)));
if (!_mm_movemask_ps(mask))
return mask;
}
a = tnear;
b = tfar;
return mask;
}