instancing works
parent
57d13dfe7b
commit
37d06c5623
|
@ -270,6 +270,90 @@ protected:
|
||||||
};
|
};
|
||||||
#endif
|
#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 destructor
|
||||||
virtual ~KDTree();
|
virtual ~KDTree();
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -206,7 +206,7 @@ public:
|
||||||
* \brief Given that an intersection has been found, create a
|
* \brief Given that an intersection has been found, create a
|
||||||
* detailed intersection record
|
* detailed intersection record
|
||||||
*/
|
*/
|
||||||
virtual void fillIntersectionRecord(const Ray &ray, Float t,
|
virtual void fillIntersectionRecord(const Ray &ray,
|
||||||
const void *temp, Intersection &its) const;
|
const void *temp, Intersection &its) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,4 +5,5 @@ if [[ "$unamestr" == 'Darwin' ]]; then
|
||||||
else
|
else
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/src/libcore:`pwd`/src/librender:`pwd`/src/libhw
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/src/libcore:`pwd`/src/librender:`pwd`/src/libhw
|
||||||
export PATH=`pwd`:$PATH
|
export PATH=`pwd`:$PATH
|
||||||
|
ulimit -c 1000000000
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -121,82 +121,8 @@ bool KDTree::rayIntersect(const Ray &ray, Intersection &its) const {
|
||||||
|
|
||||||
if (EXPECT_TAKEN(maxt > mint)) {
|
if (EXPECT_TAKEN(maxt > mint)) {
|
||||||
if (rayIntersectHavran<false>(ray, mint, maxt, its.t, temp)) {
|
if (rayIntersectHavran<false>(ray, mint, maxt, its.t, temp)) {
|
||||||
/* After having found a unique intersection, fill a proper record
|
fillIntersectionRecord<true>(ray, temp, its);
|
||||||
using the temporary information collected in \ref intersect() */
|
return true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]),
|
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])
|
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx])
|
||||||
);
|
);
|
||||||
shape->fillIntersectionRecord(ray, its4.t.f[idx], temp +
|
its.t = its4.t.f[idx];
|
||||||
+ idx * MTS_KD_INTERSECTION_TEMP + 8, its);
|
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];
|
wo.x = nSecD[0].f[idx]; wo.y = nSecD[1].f[idx]; wo.z = nSecD[2].f[idx];
|
||||||
|
|
|
@ -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 {
|
const void *temp, Intersection &its) const {
|
||||||
Log(EError, "%s::fillIntersectionRecord(): Not implemented!",
|
Log(EError, "%s::fillIntersectionRecord(): Not implemented!",
|
||||||
getClass()->getName().c_str());
|
getClass()->getName().c_str());
|
||||||
|
|
|
@ -151,9 +151,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillIntersectionRecord(const Ray &ray, Float t,
|
void fillIntersectionRecord(const Ray &ray,
|
||||||
const void *temp, Intersection &its) const {
|
const void *temp, Intersection &its) const {
|
||||||
its.p = ray(t);
|
its.p = ray(its.t);
|
||||||
|
|
||||||
Point local = m_worldToObject(its.p);
|
Point local = m_worldToObject(its.p);
|
||||||
Float phi = std::atan2(local.y, local.x);
|
Float phi = std::atan2(local.y, local.x);
|
||||||
|
|
|
@ -612,9 +612,9 @@ public:
|
||||||
return m_kdtree->rayIntersect(ray, mint, maxt);
|
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 {
|
const void *temp, Intersection &its) const {
|
||||||
its.p = ray(t);
|
its.p = ray(its.t);
|
||||||
|
|
||||||
/* No UV coordinates for now */
|
/* No UV coordinates for now */
|
||||||
its.uv = Point2(0,0);
|
its.uv = Point2(0,0);
|
||||||
|
|
|
@ -107,10 +107,17 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillIntersectionRecord(const Ray &ray, Float t,
|
void fillIntersectionRecord(const Ray &ray,
|
||||||
const void *temp, Intersection &its) const {
|
const void *temp, Intersection &its) const {
|
||||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
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()
|
MTS_DECLARE_CLASS()
|
||||||
|
|
|
@ -60,6 +60,10 @@ void ShapeGroup::addChild(const std::string &name, ConfigurableObject *child) {
|
||||||
Log(EError, "Nested instancing is not supported!");
|
Log(EError, "Nested instancing is not supported!");
|
||||||
} else if (cClass->derivesFrom(Shape::m_theClass)) {
|
} else if (cClass->derivesFrom(Shape::m_theClass)) {
|
||||||
Shape *shape = static_cast<Shape *>(child);
|
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()) {
|
if (shape->isCompound()) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -130,10 +130,9 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillIntersectionRecord(const Ray &ray, Float t,
|
void fillIntersectionRecord(const Ray &ray,
|
||||||
const void *temp, Intersection &its) const {
|
const void *temp, Intersection &its) const {
|
||||||
its.t = t;
|
its.p = ray(its.t);
|
||||||
its.p = ray(t);
|
|
||||||
Vector local = m_worldToObject(its.p - m_center);
|
Vector local = m_worldToObject(its.p - m_center);
|
||||||
Float theta = std::acos(std::min(std::max(local.z/m_radius,
|
Float theta = std::acos(std::min(std::max(local.z/m_radius,
|
||||||
-(Float) 1), (Float) 1));
|
-(Float) 1), (Float) 1));
|
||||||
|
|
|
@ -50,7 +50,7 @@ class mitsuba_lamp(declarative_property_group):
|
||||||
'type': 'float',
|
'type': 'float',
|
||||||
'attr': 'sampling_weight',
|
'attr': 'sampling_weight',
|
||||||
'name': '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,
|
'default': 1.0,
|
||||||
'min': 1e-3,
|
'min': 1e-3,
|
||||||
'soft_min': 1e-3,
|
'soft_min': 1e-3,
|
||||||
|
|
Loading…
Reference in New Issue