1 | #include "dxstdafx.h"
|
---|
2 | #include "transformed.h"
|
---|
3 | #include "Radion.hpp"
|
---|
4 |
|
---|
5 |
|
---|
6 | bool Transformed::intersect(const Ray& ray, float& depth, float rayMin, float rayMax)
|
---|
7 | {
|
---|
8 | Ray tfdRay;
|
---|
9 | worldToModel.transformPoint(ray.origin, tfdRay.origin);
|
---|
10 | worldToModel.transformDirection(ray.dir, tfdRay.dir);
|
---|
11 | float iscale = tfdRay.dir.norm();
|
---|
12 | float scale = 1.0f / iscale;
|
---|
13 | tfdRay.dir *= scale;
|
---|
14 | tfdRay.id = ray.id;
|
---|
15 | tfdRay.isShadowRay = ray.isShadowRay;
|
---|
16 | object->intersect(tfdRay, depth, rayMin * iscale, rayMax * iscale);
|
---|
17 | lastTestedRayId = object->lastTestedRayId;
|
---|
18 | lastTestedRayResult = object->lastTestedRayResult;
|
---|
19 | if(!ray.isShadowRay)
|
---|
20 | {
|
---|
21 | modelToWorld.transformDirection(object->lastTestedRayResult.normal, lastTestedRayResult.normal);
|
---|
22 | lastTestedRayResult.normal.normalize();
|
---|
23 | modelToWorld.transformPoint(object->lastTestedRayResult.point, lastTestedRayResult.point);
|
---|
24 | lastTestedRayResult.object = this;
|
---|
25 | }
|
---|
26 | depth = lastTestedRayResult.depth = object->lastTestedRayResult.depth * scale;
|
---|
27 | return lastTestedRayResult.isIntersect;
|
---|
28 | }
|
---|
29 |
|
---|
30 | bool Transformed::intersectBackSide(const Ray& ray, float& depth, float rayMin, float rayMax)
|
---|
31 | {
|
---|
32 | Ray tfdRay;
|
---|
33 | worldToModel.transformPoint(ray.origin, tfdRay.origin);
|
---|
34 | worldToModel.transformDirection(ray.dir, tfdRay.dir);
|
---|
35 | float iscale = tfdRay.dir.norm();
|
---|
36 | float scale = 1.0f / iscale;
|
---|
37 | tfdRay.dir *= scale;
|
---|
38 | tfdRay.id = ray.id;
|
---|
39 | tfdRay.isShadowRay = ray.isShadowRay;
|
---|
40 | object->intersectBackSide(tfdRay, depth, rayMin * iscale, rayMax * iscale);
|
---|
41 | lastTestedRayId = object->lastTestedRayId;
|
---|
42 | lastTestedRayResult = object->lastTestedRayResult;
|
---|
43 | if(!ray.isShadowRay)
|
---|
44 | {
|
---|
45 | modelToWorld.transformDirection(object->lastTestedRayResult.normal, lastTestedRayResult.normal);
|
---|
46 | lastTestedRayResult.normal.normalize();
|
---|
47 | modelToWorld.transformPoint(object->lastTestedRayResult.point, lastTestedRayResult.point);
|
---|
48 | lastTestedRayResult.object = this;
|
---|
49 | }
|
---|
50 | depth = lastTestedRayResult.depth = object->lastTestedRayResult.depth * scale;
|
---|
51 | return lastTestedRayResult.isIntersect;
|
---|
52 | }
|
---|
53 |
|
---|
54 | void Transformed::translate(Vector translation)
|
---|
55 | {
|
---|
56 | modelToWorld.t[0] += translation[0];
|
---|
57 | modelToWorld.t[1] += translation[1];
|
---|
58 | modelToWorld.t[2] += translation[2];
|
---|
59 | worldToModel.setInvert(modelToWorld);
|
---|
60 | // bbox.minPoint -= translation;
|
---|
61 | // bbox.maxPoint -= translation;
|
---|
62 | object->getTransformedBoundingBox(modelToWorld, bbox);
|
---|
63 | }
|
---|
64 |
|
---|
65 | void Transformed::rotateZ(float angle)
|
---|
66 | {
|
---|
67 | modelToWorld.rotateZ(angle);
|
---|
68 | worldToModel.setInvert(modelToWorld);
|
---|
69 | object->getTransformedBoundingBox(modelToWorld, bbox);
|
---|
70 | }
|
---|
71 |
|
---|
72 | void Transformed::rotateY(float angle)
|
---|
73 | {
|
---|
74 | modelToWorld.rotateY(angle);
|
---|
75 | worldToModel.setInvert(modelToWorld);
|
---|
76 | object->getTransformedBoundingBox(modelToWorld, bbox);
|
---|
77 | }
|
---|
78 |
|
---|
79 | void Transformed::rotateX(float angle)
|
---|
80 | {
|
---|
81 | modelToWorld.rotateX(angle);
|
---|
82 | worldToModel.setInvert(modelToWorld);
|
---|
83 | object->getTransformedBoundingBox(modelToWorld, bbox);
|
---|
84 | }
|
---|
85 |
|
---|
86 | void Transformed::scale(float factor)
|
---|
87 | {
|
---|
88 | modelToWorld.scale(factor);
|
---|
89 | worldToModel.setInvert(modelToWorld);
|
---|
90 | object->getTransformedBoundingBox(modelToWorld, bbox);
|
---|
91 | }
|
---|
92 |
|
---|
93 | void Transformed::setTransforms(D3DXMATRIX& mw, D3DXMATRIX& itmw)
|
---|
94 | {
|
---|
95 | modelToWorld.fill(mw[0]/(mw[3]+mw[15]), mw[1]/(mw[3]+mw[15]), mw[2]/(mw[3]+mw[15]),
|
---|
96 | mw[4]/(mw[7]+mw[15]), mw[5]/(mw[7]+mw[15]), mw[6]/(mw[7]+mw[15]),
|
---|
97 | mw[8]/(mw[11]+mw[15]), mw[9]/(mw[11]+mw[15]), mw[10]/(mw[11]+mw[15]),
|
---|
98 | mw[12]/mw[15], mw[13]/mw[15], mw[14]/mw[15]);
|
---|
99 | worldToModel.setInvert(modelToWorld);
|
---|
100 | }
|
---|
101 |
|
---|
102 | float Transformed::getSurfaceArea()
|
---|
103 | {
|
---|
104 | Vector si(1.0f, 0.0f, 0.0f);
|
---|
105 | Vector su;
|
---|
106 | worldToModel.transformDirection(si, su);
|
---|
107 | return object->getSurfaceArea() * su.norm2();
|
---|
108 | }
|
---|
109 |
|
---|
110 | void Transformed::sampleSurface(Radion& radion)
|
---|
111 | {
|
---|
112 | object->sampleSurface(radion);
|
---|
113 | Vector trpos, trnorm;
|
---|
114 | modelToWorld.transformPoint(radion.position, trpos);
|
---|
115 | worldToModel.transformDirectionTransposed(radion.normal, trnorm);
|
---|
116 | radion.position = trpos;
|
---|
117 | radion.normal = trnorm;
|
---|
118 | radion.normal.normalize();
|
---|
119 | Vector si(1.0f, 0.0f, 0.0f);
|
---|
120 | Vector su;
|
---|
121 | worldToModel.transformDirection(si, su);
|
---|
122 | radion.radiance.z /= su.norm2();
|
---|
123 | } |
---|