#include "dxstdafx.h" #include "transformed.h" #include "Radion.hpp" bool Transformed::intersect(const Ray& ray, float& depth, float rayMin, float rayMax) { Ray tfdRay; worldToModel.transformPoint(ray.origin, tfdRay.origin); worldToModel.transformDirection(ray.dir, tfdRay.dir); float iscale = tfdRay.dir.norm(); float scale = 1.0f / iscale; tfdRay.dir *= scale; tfdRay.id = ray.id; tfdRay.isShadowRay = ray.isShadowRay; object->intersect(tfdRay, depth, rayMin * iscale, rayMax * iscale); lastTestedRayId = object->lastTestedRayId; lastTestedRayResult = object->lastTestedRayResult; if(!ray.isShadowRay) { modelToWorld.transformDirection(object->lastTestedRayResult.normal, lastTestedRayResult.normal); lastTestedRayResult.normal.normalize(); modelToWorld.transformPoint(object->lastTestedRayResult.point, lastTestedRayResult.point); lastTestedRayResult.object = this; } depth = lastTestedRayResult.depth = object->lastTestedRayResult.depth * scale; return lastTestedRayResult.isIntersect; } bool Transformed::intersectBackSide(const Ray& ray, float& depth, float rayMin, float rayMax) { Ray tfdRay; worldToModel.transformPoint(ray.origin, tfdRay.origin); worldToModel.transformDirection(ray.dir, tfdRay.dir); float iscale = tfdRay.dir.norm(); float scale = 1.0f / iscale; tfdRay.dir *= scale; tfdRay.id = ray.id; tfdRay.isShadowRay = ray.isShadowRay; object->intersectBackSide(tfdRay, depth, rayMin * iscale, rayMax * iscale); lastTestedRayId = object->lastTestedRayId; lastTestedRayResult = object->lastTestedRayResult; if(!ray.isShadowRay) { modelToWorld.transformDirection(object->lastTestedRayResult.normal, lastTestedRayResult.normal); lastTestedRayResult.normal.normalize(); modelToWorld.transformPoint(object->lastTestedRayResult.point, lastTestedRayResult.point); lastTestedRayResult.object = this; } depth = lastTestedRayResult.depth = object->lastTestedRayResult.depth * scale; return lastTestedRayResult.isIntersect; } void Transformed::translate(Vector translation) { modelToWorld.t[0] += translation[0]; modelToWorld.t[1] += translation[1]; modelToWorld.t[2] += translation[2]; worldToModel.setInvert(modelToWorld); // bbox.minPoint -= translation; // bbox.maxPoint -= translation; object->getTransformedBoundingBox(modelToWorld, bbox); } void Transformed::rotateZ(float angle) { modelToWorld.rotateZ(angle); worldToModel.setInvert(modelToWorld); object->getTransformedBoundingBox(modelToWorld, bbox); } void Transformed::rotateY(float angle) { modelToWorld.rotateY(angle); worldToModel.setInvert(modelToWorld); object->getTransformedBoundingBox(modelToWorld, bbox); } void Transformed::rotateX(float angle) { modelToWorld.rotateX(angle); worldToModel.setInvert(modelToWorld); object->getTransformedBoundingBox(modelToWorld, bbox); } void Transformed::scale(float factor) { modelToWorld.scale(factor); worldToModel.setInvert(modelToWorld); object->getTransformedBoundingBox(modelToWorld, bbox); } void Transformed::setTransforms(D3DXMATRIX& mw, D3DXMATRIX& itmw) { modelToWorld.fill(mw[0]/(mw[3]+mw[15]), mw[1]/(mw[3]+mw[15]), mw[2]/(mw[3]+mw[15]), mw[4]/(mw[7]+mw[15]), mw[5]/(mw[7]+mw[15]), mw[6]/(mw[7]+mw[15]), mw[8]/(mw[11]+mw[15]), mw[9]/(mw[11]+mw[15]), mw[10]/(mw[11]+mw[15]), mw[12]/mw[15], mw[13]/mw[15], mw[14]/mw[15]); worldToModel.setInvert(modelToWorld); } float Transformed::getSurfaceArea() { Vector si(1.0f, 0.0f, 0.0f); Vector su; worldToModel.transformDirection(si, su); return object->getSurfaceArea() * su.norm2(); } void Transformed::sampleSurface(Radion& radion) { object->sampleSurface(radion); Vector trpos, trnorm; modelToWorld.transformPoint(radion.position, trpos); worldToModel.transformDirectionTransposed(radion.normal, trnorm); radion.position = trpos; radion.normal = trnorm; radion.normal.normalize(); Vector si(1.0f, 0.0f, 0.0f); Vector su; worldToModel.transformDirection(si, su); radion.radiance.z /= su.norm2(); }