instancing works

metadata
Wenzel Jakob 2010-11-12 11:03:43 +01:00
parent 57d13dfe7b
commit 37d06c5623
12 changed files with 111 additions and 90 deletions

View File

@ -270,6 +270,90 @@ protected:
};
#endif
/**
* \brief After having found a unique intersection, fill a proper record
* using the temporary information collected in \ref intersect()
*/
template<bool BarycentricPos> FINLINE void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
const IntersectionCache *cache = reinterpret_cast<const IntersectionCache *>(temp);
const Shape *shape = m_shapes[cache->shapeIndex];
if (m_triangleFlag[cache->shapeIndex]) {
const TriMesh *trimesh = static_cast<const TriMesh *>(shape);
const Triangle &tri = trimesh->getTriangles()[cache->primIndex];
const Point *vertexPositions = trimesh->getVertexPositions();
const Normal *vertexNormals = trimesh->getVertexNormals();
const Point2 *vertexTexcoords = trimesh->getVertexTexcoords();
const Spectrum *vertexColors = trimesh->getVertexColors();
const TangentSpace *vertexTangents = trimesh->getVertexTangents();
const Vector b(1 - cache->u - cache->v, cache->u, cache->v);
const uint32_t idx0 = tri.idx[0], idx1 = tri.idx[1], idx2 = tri.idx[2];
const Point &p0 = vertexPositions[idx0];
const Point &p1 = vertexPositions[idx1];
const Point &p2 = vertexPositions[idx2];
if (BarycentricPos)
its.p = p0 * b.x + p1 * b.y + p2 * b.z;
else
its.p = ray(its.t);
Normal faceNormal(cross(p1-p0, p2-p0));
Float length = faceNormal.length();
if (!faceNormal.isZero())
faceNormal /= length;
its.geoFrame = Frame(faceNormal);
if (EXPECT_TAKEN(vertexNormals)) {
const Normal &n0 = vertexNormals[idx0];
const Normal &n1 = vertexNormals[idx1];
const Normal &n2 = vertexNormals[idx2];
if (EXPECT_TAKEN(!vertexTangents)) {
its.shFrame = Frame(normalize(n0 * b.x + n1 * b.y + n2 * b.z));
} else {
const TangentSpace &t0 = vertexTangents[idx0];
const TangentSpace &t1 = vertexTangents[idx1];
const TangentSpace &t2 = vertexTangents[idx2];
const Vector dpdu = t0.dpdu * b.x + t1.dpdu * b.y + t2.dpdu * b.z;
its.shFrame.n = normalize(n0 * b.x + n1 * b.y + n2 * b.z);
its.shFrame.s = normalize(dpdu - its.shFrame.n
* dot(its.shFrame.n, dpdu));
its.shFrame.t = cross(its.shFrame.n, its.shFrame.s);
its.dpdu = dpdu;
its.dpdv = t0.dpdv * b.x + t1.dpdv * b.y + t2.dpdv * b.z;
}
} else {
its.shFrame = its.geoFrame;
}
if (EXPECT_TAKEN(vertexTexcoords)) {
const Point2 &t0 = vertexTexcoords[idx0];
const Point2 &t1 = vertexTexcoords[idx1];
const Point2 &t2 = vertexTexcoords[idx2];
its.uv = t0 * b.x + t1 * b.y + t2 * b.z;
} else {
its.uv = Point2(0.0f);
}
if (EXPECT_NOT_TAKEN(vertexColors)) {
const Spectrum &c0 = vertexColors[idx0],
&c1 = vertexColors[idx1],
&c2 = vertexColors[idx2];
its.color = c0 * b.x + c1 * b.y + c2 * b.z;
}
its.wi = its.toLocal(-ray.d);
its.shape = trimesh;
its.hasUVPartials = false;
} else {
shape->fillIntersectionRecord(ray,
reinterpret_cast<const uint8_t*>(temp) + 8, its);
}
}
/// Virtual destructor
virtual ~KDTree();
private:

View File

@ -206,7 +206,7 @@ public:
* \brief Given that an intersection has been found, create a
* detailed intersection record
*/
virtual void fillIntersectionRecord(const Ray &ray, Float t,
virtual void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const;
/**

View File

@ -5,4 +5,5 @@ if [[ "$unamestr" == 'Darwin' ]]; then
else
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/src/libcore:`pwd`/src/librender:`pwd`/src/libhw
export PATH=`pwd`:$PATH
ulimit -c 1000000000
fi

View File

@ -121,82 +121,8 @@ bool KDTree::rayIntersect(const Ray &ray, Intersection &its) const {
if (EXPECT_TAKEN(maxt > mint)) {
if (rayIntersectHavran<false>(ray, mint, maxt, its.t, temp)) {
/* After having found a unique intersection, fill a proper record
using the temporary information collected in \ref intersect() */
const IntersectionCache *cache = reinterpret_cast<const IntersectionCache *>(temp);
const Shape *shape = m_shapes[cache->shapeIndex];
if (m_triangleFlag[cache->shapeIndex]) {
const TriMesh *trimesh = static_cast<const TriMesh *>(shape);
const Triangle &tri = trimesh->getTriangles()[cache->primIndex];
const Point *vertexPositions = trimesh->getVertexPositions();
const Normal *vertexNormals = trimesh->getVertexNormals();
const Point2 *vertexTexcoords = trimesh->getVertexTexcoords();
const Spectrum *vertexColors = trimesh->getVertexColors();
const TangentSpace *vertexTangents = trimesh->getVertexTangents();
const Vector b(1 - cache->u - cache->v, cache->u, cache->v);
const uint32_t idx0 = tri.idx[0], idx1 = tri.idx[1], idx2 = tri.idx[2];
const Point &p0 = vertexPositions[idx0];
const Point &p1 = vertexPositions[idx1];
const Point &p2 = vertexPositions[idx2];
//its.p = ray(its.t);
its.p = p0 * b.x + p1 * b.y + p2 * b.z;
Normal faceNormal(cross(p1-p0, p2-p0));
Float length = faceNormal.length();
if (!faceNormal.isZero())
faceNormal /= length;
its.geoFrame = Frame(faceNormal);
if (EXPECT_TAKEN(vertexNormals)) {
const Normal &n0 = vertexNormals[idx0];
const Normal &n1 = vertexNormals[idx1];
const Normal &n2 = vertexNormals[idx2];
if (EXPECT_TAKEN(!vertexTangents)) {
its.shFrame = Frame(normalize(n0 * b.x + n1 * b.y + n2 * b.z));
} else {
const TangentSpace &t0 = vertexTangents[idx0];
const TangentSpace &t1 = vertexTangents[idx1];
const TangentSpace &t2 = vertexTangents[idx2];
const Vector dpdu = t0.dpdu * b.x + t1.dpdu * b.y + t2.dpdu * b.z;
its.shFrame.n = normalize(n0 * b.x + n1 * b.y + n2 * b.z);
its.shFrame.s = normalize(dpdu - its.shFrame.n
* dot(its.shFrame.n, dpdu));
its.shFrame.t = cross(its.shFrame.n, its.shFrame.s);
its.dpdu = dpdu;
its.dpdv = t0.dpdv * b.x + t1.dpdv * b.y + t2.dpdv * b.z;
}
} else {
its.shFrame = its.geoFrame;
}
if (EXPECT_TAKEN(vertexTexcoords)) {
const Point2 &t0 = vertexTexcoords[idx0];
const Point2 &t1 = vertexTexcoords[idx1];
const Point2 &t2 = vertexTexcoords[idx2];
its.uv = t0 * b.x + t1 * b.y + t2 * b.z;
} else {
its.uv = Point2(0.0f);
}
if (EXPECT_NOT_TAKEN(vertexColors)) {
const Spectrum &c0 = vertexColors[idx0],
&c1 = vertexColors[idx1],
&c2 = vertexColors[idx2];
its.color = c0 * b.x + c1 * b.y + c2 * b.z;
}
its.wi = its.toLocal(-ray.d);
its.shape = trimesh;
its.hasUVPartials = false;
return true;
} else {
shape->fillIntersectionRecord(ray, its.t,
reinterpret_cast<const uint8_t*>(temp) + 8, its);
return true;
}
fillIntersectionRecord<true>(ray, temp, its);
return true;
}
}
}

View File

@ -348,8 +348,8 @@ void PreviewWorker::processCoherent(const WorkUnit *workUnit, WorkResult *workRe
Point(primRay4.o[0].f[idx], primRay4.o[1].f[idx], primRay4.o[2].f[idx]),
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx])
);
shape->fillIntersectionRecord(ray, its4.t.f[idx], temp +
+ idx * MTS_KD_INTERSECTION_TEMP + 8, its);
its.t = its4.t.f[idx];
shape->fillIntersectionRecord(ray, temp + idx * MTS_KD_INTERSECTION_TEMP + 8, its);
}
wo.x = nSecD[0].f[idx]; wo.y = nSecD[1].f[idx]; wo.z = nSecD[2].f[idx];

View File

@ -127,7 +127,7 @@ bool Shape::rayIntersect(const Ray &ray, Float mint,
}
void Shape::fillIntersectionRecord(const Ray &ray, Float t,
void Shape::fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
Log(EError, "%s::fillIntersectionRecord(): Not implemented!",
getClass()->getName().c_str());

View File

@ -151,9 +151,9 @@ public:
}
}
void fillIntersectionRecord(const Ray &ray, Float t,
void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
its.p = ray(t);
its.p = ray(its.t);
Point local = m_worldToObject(its.p);
Float phi = std::atan2(local.y, local.x);

View File

@ -612,9 +612,9 @@ public:
return m_kdtree->rayIntersect(ray, mint, maxt);
}
void fillIntersectionRecord(const Ray &ray, Float t,
void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
its.p = ray(t);
its.p = ray(its.t);
/* No UV coordinates for now */
its.uv = Point2(0,0);

View File

@ -107,10 +107,17 @@ public:
return false;
}
void fillIntersectionRecord(const Ray &ray, Float t,
void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
const KDTree *kdtree = m_shapeGroup->getKDTree();
Log(EError, "fillIntersectionRecord(): Unsupported!");
kdtree->fillIntersectionRecord<false>(ray, temp, its);
its.shFrame.n = normalize(m_objectToWorld(its.shFrame.n));
its.shFrame.s = normalize(m_objectToWorld(its.shFrame.s));
its.shFrame.t = normalize(m_objectToWorld(its.shFrame.t));
its.geoFrame = Frame(normalize(m_objectToWorld(its.geoFrame.n)));
its.wi = its.shFrame.toLocal(-ray.d);
its.dpdu = m_objectToWorld(its.dpdu);
its.dpdv = m_objectToWorld(its.dpdv);
}
MTS_DECLARE_CLASS()

View File

@ -60,6 +60,10 @@ void ShapeGroup::addChild(const std::string &name, ConfigurableObject *child) {
Log(EError, "Nested instancing is not supported!");
} else if (cClass->derivesFrom(Shape::m_theClass)) {
Shape *shape = static_cast<Shape *>(child);
if (shape->isLuminaire())
Log(EError, "Instancing of luminaires is not supported");
if (shape->hasSubsurface())
Log(EError, "Instancing of subsurface integrators is not supported");
if (shape->isCompound()) {
int index = 0;
do {

View File

@ -130,10 +130,9 @@ public:
return true;
}
void fillIntersectionRecord(const Ray &ray, Float t,
void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
its.t = t;
its.p = ray(t);
its.p = ray(its.t);
Vector local = m_worldToObject(its.p - m_center);
Float theta = std::acos(std::min(std::max(local.z/m_radius,
-(Float) 1), (Float) 1));

View File

@ -50,7 +50,7 @@ class mitsuba_lamp(declarative_property_group):
'type': 'float',
'attr': 'sampling_weight',
'name': 'Sampling weight',
'description': 'Determines the relative amount of samples for this light source',
'description': 'Relative amount of samples to place on this light source (e.g. the "importance")',
'default': 1.0,
'min': 1e-3,
'soft_min': 1e-3,