reflection geometry finally correct
[laserbrain_demo] / src / metascene.cc
index 82cf669..eef5e65 100644 (file)
@@ -108,7 +108,7 @@ void MetaScene::update(float dt)
                static bool once;
                if(!once) {
                        float x = ImGui::GetColumnOffset(1);
-                       ImGui::SetColumnOffset(1, x * 1.7);
+                       ImGui::SetColumnOffset(1, x * 1.55);
                        once = true;
                }
        }
@@ -180,7 +180,7 @@ std::list<SceneNode*> MetaScene::match_nodes(const char *qstr) const
                        res.splice(res.end(), tmp);
                }
        }
-       return std::move(res);
+       return res;     // hopefully it'll be moved
 }
 
 Scene *MetaScene::extract_nodes(const char *qstr)
@@ -203,6 +203,8 @@ Scene *MetaScene::extract_nodes(const char *qstr)
 
 int MetaScene::calc_mirror_planes()
 {
+       FlatMirror *planes = 0;
+
        int num_mirrors = 0;
        while(mirrors) {
                FlatMirror *m = mirrors;
@@ -226,6 +228,7 @@ int MetaScene::calc_mirror_planes()
 
                                FlatMirror *mir = new FlatMirror;
                                mir->reflect = obj->mtl.reflect;
+                               mir->node = obj->node;
 
                                if(obj->mtl.flat_mirror == MTL_MIRROR_AUTO) {
                                        // grab the first triangle and make a plane
@@ -237,31 +240,47 @@ int MetaScene::calc_mirror_planes()
                                        mir->plane.normal = face.normal;
                                } else {
                                        int plane_idx = obj->mtl.flat_mirror - MTL_MIRROR_AABB_PX;
-                                       if(obj->node) {
-                                               mir->plane = obj->node->get_bounds().get_plane(plane_idx);
-                                       } else {
-                                               mir->plane = obj->get_aabox().get_plane(plane_idx);
-                                       }
-                                       debug_log("mirror plane: p(%f %f %f) n(%f %f %f)\n", mir->plane.pt.x, mir->plane.pt.y,
-                                                       mir->plane.pt.z, mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z);
+                                       mir->plane = obj->get_aabox().get_plane(plane_idx);
+                               }
+
+                               mir->wplane = mir->plane;
+                               if(obj->node) {
+                                       const Mat4 &xform = obj->node->get_matrix();
+                                       mir->wplane.pt = xform * mir->wplane.pt;
+                                       mir->wplane.normal = normalize(xform.upper3x3() * mir->wplane.normal);
                                }
 
                                // check to see if we have found this mirror plane already
                                bool found = false;
-                               FlatMirror *node = mirrors;
+                               FlatMirror *node = planes;
                                while(node) {
-                                       if(1.0f - dot(mir->plane.normal, node->plane.normal) < 1e-4f &&
-                                                       fabs(dot(mir->plane.normal, normalize(mir->plane.pt - node->plane.pt))) < 1e-4) {
+                                       float d1 = dot(mir->wplane.normal, mir->wplane.pt);
+                                       float d2 = dot(node->wplane.normal, node->wplane.pt);
+
+                                       if(1.0f - dot(mir->wplane.normal, node->wplane.normal) < 1e-4f &&
+                                                       fabs(d1 - d2) < 1e-4) {
                                                found = true;
                                                break;
                                        }
                                        node = node->next;
                                }
 
+                               debug_log("[%s@%s] mirror plane: local(%g %g %g %g), world(%g %g %g %g)%s\n",
+                                               obj->get_name(), obj->node ? obj->node->get_name() : "<no-node>",
+                                               mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z,
+                                               dot(mir->plane.normal, mir->plane.pt), mir->wplane.normal.x, mir->wplane.normal.y,
+                                               mir->wplane.normal.z, dot(mir->wplane.normal, mir->wplane.pt), found ? " duplicate" : "");
+
                                if(!found) {
                                        mir->next = mirrors;
                                        mirrors = mir;
 
+                                       node = new FlatMirror;
+                                       node->wplane = mir->wplane;
+                                       node->next = planes;
+                                       planes = node;
+
+                                       mir->objects.push_back(obj);
                                        objmirror[obj] = mir;   // associate with object
                                        ++num_mirrors;
                                } else {
@@ -271,6 +290,12 @@ int MetaScene::calc_mirror_planes()
                }
        }
 
+       while(planes) {
+               FlatMirror *tmp = planes;
+               planes = planes->next;
+               delete tmp;
+       }
+
        return num_mirrors;
 }
 
@@ -523,13 +548,13 @@ static bool proc_mtledit(MetaScene *mscn, MaterialEdit *med, struct ts_node *nod
 
                                        switch(tolower(caxis)) {
                                        case 'x':
-                                               plane = caxis == '+' ? MTL_MIRROR_AABB_PX : MTL_MIRROR_AABB_NX;
+                                               plane = csign == '+' ? MTL_MIRROR_AABB_PX : MTL_MIRROR_AABB_NX;
                                                break;
                                        case 'y':
-                                               plane = caxis == '+' ? MTL_MIRROR_AABB_PY : MTL_MIRROR_AABB_NY;
+                                               plane = csign == '+' ? MTL_MIRROR_AABB_PY : MTL_MIRROR_AABB_NY;
                                                break;
                                        case 'z':
-                                               plane = caxis == '+' ? MTL_MIRROR_AABB_PZ : MTL_MIRROR_AABB_NZ;
+                                               plane = csign == '+' ? MTL_MIRROR_AABB_PZ : MTL_MIRROR_AABB_NZ;
                                                break;
                                        default:
                                                error_log("invalid reflect plane specifier: %s\n", aplane->val.str);