Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r629 - in branches/itanium2: Model/Groups fox


Chronological Thread 
  • From: hansong@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r629 - in branches/itanium2: Model/Groups fox
  • Date: Sat, 15 Oct 2005 10:39:15 -0600 (MDT)

Author: hansong
Date: Sat Oct 15 10:39:09 2005
New Revision: 629

Modified:
   branches/itanium2/Model/Groups/KDTree.cc
   branches/itanium2/Model/Groups/KDTree.h
   branches/itanium2/Model/Groups/KDTreeLoader.cc
   branches/itanium2/Model/Groups/TransparentKDTree.cc
   branches/itanium2/Model/Groups/TransparentKDTree.h
   branches/itanium2/fox/FMantaWindow.cc
   branches/itanium2/fox/FMantaWindow.h
   branches/itanium2/fox/dm_demo.cc
Log:
Add picking. two additional files, .grp and .name, are used to provide 
per-triangle group numbers, and per-group part names. When the KDTree data 
structures (both KDTree and TransparentKDTree) are set to picking mode, the 
hit triangle is recorded, and the object's range of triangles to which the 
hit triangle belongs to is computed. The range of triangles are subsequently 
displayed in inverted color. The user interface of picking is currently part 
of the Fox GUI, using a Double click of the Right mouse button. Note that 
picking should be done when only one ray/raypacket is in flight - in Fox it's 
in the transaction handling part.

Modified: branches/itanium2/Model/Groups/KDTree.cc
==============================================================================
--- branches/itanium2/Model/Groups/KDTree.cc    (original)
+++ branches/itanium2/Model/Groups/KDTree.cc    Sat Oct 15 10:39:09 2005
@@ -323,6 +323,21 @@
                              &isectData,
                              context, mailbox ) && 
                                        (isectData.rayHitTriIndex >= 0)) {
+
+                                       if (isPickingEnabled()) {
+                                               pickedTri = 
isectData.rayHitTriIndex;
+                                               cerr << "picked " << 
pickedTri << "\n";
+                                               pickedBeginIndex = 
pickedEndIndex = pickedTri;
+                                               while (pickedBeginIndex > 0 &&
+                                                       
triToGroupMap->get(pickedBeginIndex-1)
+                                                               == 
triToGroupMap->get(pickedBeginIndex))
+                                                       pickedBeginIndex --;
+                                               while (pickedEndIndex < 
tris->getLen()-1 &&
+                                                       
triToGroupMap->get(pickedEndIndex+1)
+                                                               == 
triToGroupMap->get(pickedEndIndex))
+                                                       pickedEndIndex ++;
+                                               cerr << "picked begin " << 
pickedBeginIndex << " end " << pickedEndIndex << "\n";
+                                       }
                                
                                
                                
@@ -347,7 +362,13 @@
           else
             e.hitInfo.scratchpad<ScratchPadInfo>().payload = 
Color(RGB(0.0,0.0,1.0));
 #else          
-          e.hitInfo.scratchpad<ScratchPadInfo>().payload = 
tris->get(isectData.rayHitTriIndex).payload;
+                       if (pickedTri > 0 &&
+                                pickedBeginIndex <= isectData.rayHitTriIndex 
&&
+                                isectData.rayHitTriIndex <= pickedEndIndex) {
+                               Color &c = 
tris->get(isectData.rayHitTriIndex).payload;
+                       e.hitInfo.scratchpad<ScratchPadInfo>().payload = 
Color(RGB(1,1,1))-c;
+                       } else
+                       e.hitInfo.scratchpad<ScratchPadInfo>().payload = 
tris->get(isectData.rayHitTriIndex).payload;
 #endif
           // Check to make sure the found hit is inside the current cell.
           // if ((isectData.rayHit.t <= travStack[exitPos].t)/* && 
(isectData.rayHit.t > travStack[entryPos].t)*/)

Modified: branches/itanium2/Model/Groups/KDTree.h
==============================================================================
--- branches/itanium2/Model/Groups/KDTree.h     (original)
+++ branches/itanium2/Model/Groups/KDTree.h     Sat Oct 15 10:39:09 2005
@@ -289,6 +289,24 @@
       VArray<Triangle> *tris;
       Vectorf          *normals;
 
+                       VArray<int> *triToGroupMap;
+                       VArray<int> *groupToNameMap;
+                       VArray<unsigned char> *groupNames;
+                       bool __pickingEnabled;
+                       bool pickingEnabled;
+                       mutable long long pickedTri;
+                       mutable int pickedBeginIndex, pickedEndIndex;
+                       VArray<Color> pickedSavedColors;
+               public:
+                       void enablePicking() {
+                               if (__pickingEnabled)
+                                       pickingEnabled = true;
+                       }
+                       void disablePicking() { pickingEnabled = false; }
+                       bool isPickingEnabled() const { return 
pickingEnabled&&__pickingEnabled; }
+                       void resetPicking() { pickedTri = -1; }
+                       void __setPicking(bool flag) { __pickingEnabled = 
flag; }
+
     protected:
       // Copy data pointers from another kdtree. (Used by derived classes.)
       KDTree( KDTree *kdtree_, Material *material_ ) :
@@ -320,7 +338,11 @@
 
     public:
       // Constructor.
-      KDTree( Material *material_ ) : PrimitiveCommon( material_ ) {  };
+      KDTree( Material *material_ ) : PrimitiveCommon( material_ ) {  
+                 __pickingEnabled = true;
+                 pickingEnabled = false;
+                 pickedTri = -1;
+         };
 
       // This structure is used to record info about the hit.
       struct ScratchPadInfo {

Modified: branches/itanium2/Model/Groups/KDTreeLoader.cc
==============================================================================
--- branches/itanium2/Model/Groups/KDTreeLoader.cc      (original)
+++ branches/itanium2/Model/Groups/KDTreeLoader.cc      Sat Oct 15 10:39:09 
2005
@@ -450,6 +450,61 @@
                        (*indices)[i] = endian_swap( (*indices)[i] );
                }
        }
+
+       // can do picking by default
+       kdtree->__setPicking(true);
+
+       // Load group and name data
+       strcpy(filename, fn);
+       strcat(filename, ".grp");
+       fprintf(stderr, "start loading grp %s\n", filename);
+       if (! (f = fopen(filename, "rb"))) {
+               fprintf(stderr, "WARNING: cannot open .grp file; picking 
disabled\n");
+               kdtree->__setPicking(false);
+               return 1;
+       }
+       fprintf(stderr, "end loading grp\n");
+       long long nTris = kdtree->tris->getLen(); 
+       kdtree->triToGroupMap = new VArray<int>(nTris);
+       kdtree->triToGroupMap->setLen(nTris);
+       nread = fread(kdtree->triToGroupMap->getArray(), sizeof(int), nTris, 
f);
+       if (nread != nTris) {
+               fprintf(stderr, "ERROR: error reading .grp file; picking 
disabled\n");
+               kdtree->__setPicking(false);
+               return 0;
+       }
+       fclose(f);
+
+       // load name data from file
+       strcpy(filename, fn);
+       strcat(filename, ".nam");
+       if (! (f = fopen(filename, "rb"))) {
+               fprintf(stderr, "WARNING: cannot open .nam file; picking 
disabled\n");
+               kdtree->__setPicking(false);
+
+               return 1;
+       }
+       // Determine file size.
+       fseek(f, 0, SEEK_END);
+       fileSize = ftell(f);
+       fseek(f, 0, SEEK_SET);
+       kdtree->groupNames = new VArray<unsigned char>(fileSize);
+       kdtree->groupNames->setLen(fileSize);
+       nread = fread(kdtree->groupNames->getArray(), sizeof(unsigned char), 
fileSize, f);
+
+       kdtree->groupToNameMap = new VArray<int>;
+       int groupNum = 0;
+       int offset = 4; // skip the integer value in the beginning
+       while (offset < fileSize) {
+               kdtree->groupToNameMap->append(offset);
+               //fprintf(stderr, "offset %d\n", offset);
+               fprintf(stderr, "offset %d = %s\n", offset, 
&(*kdtree->groupNames)[offset]);
+               while ((*kdtree->groupNames)[offset]) // find next name
+                       offset ++;
+               offset++;
+       }
+       fprintf(stderr, "Total %d groups\n", 
kdtree->groupToNameMap->getLen());
        
        return 1;
 }
+

Modified: branches/itanium2/Model/Groups/TransparentKDTree.cc
==============================================================================
--- branches/itanium2/Model/Groups/TransparentKDTree.cc (original)
+++ branches/itanium2/Model/Groups/TransparentKDTree.cc Sat Oct 15 10:39:09 
2005
@@ -83,7 +83,15 @@
        triIndices( kdtree_->triIndices ),
        tris( kdtree_->tris ),
        normals( kdtree_->normals ),
-       sample_alpha( sample_alpha_ ) 
+       sample_alpha( sample_alpha_ ),
+                       triToGroupMap(kdtree_->triToGroupMap),
+                       groupToNameMap(kdtree_->groupToNameMap),
+                       groupNames(kdtree_->groupNames),
+                       __pickingEnabled(kdtree_->__pickingEnabled),
+                       pickingEnabled(kdtree_->pickingEnabled),
+                       pickedTri(kdtree_->pickedTri),
+                       pickedBeginIndex(kdtree_->pickedBeginIndex), 
+                       pickedEndIndex(kdtree_->pickedEndIndex)
 {
        
        bbox.extendByBox( kdtree_->bbox );
@@ -96,7 +104,7 @@
 
//////////////////////////////////////////////////////////////////////////////
 VArray<VArray<TransparentKDTree::Isect> *> 
TransparentKDTree::isectBuffers(1024, 0);
 
-int TransparentKDTree::intersectTrianglesTransparent(const Ray* ray, 
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist, 
void *userData, const RenderContext &context) const
+int TransparentKDTree::intersectTrianglesTransparent(const Ray* ray, 
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist, 
void *userData, const RenderContext &context, bool isFirst) const
 {
        int i;
        RayTriIntersectUserData *ud = (RayTriIntersectUserData*)userData;
@@ -171,15 +179,23 @@
                Real sample_alpha__ = sample_alpha;
                
                // combine  color and opacity 
+               Color c;
                for (int i=0; (i<isectbuf->getLen()) && (ray_alpha < 
(Real)0.95); i++) {
                        
-                       Color &triangle_color = tris->get( array[i].triIdx 
).payload;
+                       Color *triangle_color = &tris->get( array[i].triIdx 
).payload;
+                       if (pickedTri > 0 &&
+                                pickedBeginIndex <= array[i].triIdx &&
+                                               array[i].triIdx <= 
pickedEndIndex) {
+                               c = Color(RGB(1,1,1)) - *triangle_color;
+                               triangle_color = &c;
+                       }
+
                         
                        Real scale = Abs(Dot( normals[array[i].triIdx], 
direction ));
                        scale *= (Real)0.75;
                        scale += (Real)0.25;
                        
-                       Color sample_color = (triangle_color * scale);
+                       Color sample_color = (*triangle_color * scale);
                         
                        ray_color += (sample_color*sample_alpha__) * (1 - 
ray_alpha);
                        ray_alpha += sample_alpha__ * (1 - ray_alpha);
@@ -356,11 +372,27 @@
                        // Intersect the ray with a list of triangles.
                        if (intersectTrianglesTransparent(ray, e, 
                                                                              
                                                                              
    nearNode->listBegin(), nearNode->listSize(), 
-                                                                             
                                                                              
    travStack[exitPos].t, &isectData, context) && 
+                                                                             
                                                                              
    travStack[exitPos].t, &isectData, context, first_leaf) && 
                                        (isectData.rayHitTriIndex >= 0)) {
        
                                // If this is the first leaf, record the hit 
and normal.                        
                                if (first_leaf) {
+                                       // record hit if picking
+                                       if (isPickingEnabled()) {
+                                               pickedTri = 
isectData.rayHitTriIndex;
+                                               cerr << "picked " << 
pickedTri << "\n";
+                                               pickedBeginIndex = 
pickedEndIndex = pickedTri;
+                                               while (pickedBeginIndex > 0 &&
+                                                       
triToGroupMap->get(pickedBeginIndex-1)
+                                                               == 
triToGroupMap->get(pickedBeginIndex))
+                                                       pickedBeginIndex --;
+                                               while (pickedEndIndex < 
tris->getLen()-1 &&
+                                                       
triToGroupMap->get(pickedEndIndex+1)
+                                                               == 
triToGroupMap->get(pickedEndIndex))
+                                                       pickedEndIndex ++;
+                                               cerr << "picked begin " << 
pickedBeginIndex << "end " << pickedEndIndex << "\n";
+                                       }
+
                                        // Process the hit.
                                        e.hitInfo.hit(isectData.rayHit.t, 
material, this, 0 );
                                        

Modified: branches/itanium2/Model/Groups/TransparentKDTree.h
==============================================================================
--- branches/itanium2/Model/Groups/TransparentKDTree.h  (original)
+++ branches/itanium2/Model/Groups/TransparentKDTree.h  Sat Oct 15 10:39:09 
2005
@@ -67,11 +67,30 @@
                        VArray<int>      *triIndices;
                        VArray<Triangle> *tris;
                        Vectorf          *normals;
-                       
+
+                       VArray<int> *triToGroupMap;
+                       VArray<int> *groupToNameMap;
+                       VArray<unsigned char> *groupNames;
+                       bool __pickingEnabled;
+                       bool pickingEnabled;
+                       mutable long long pickedTri;
+                       mutable int pickedBeginIndex, pickedEndIndex;
+                       VArray<Color> pickedSavedColors;
+               public:
+                       void enablePicking() {
+                               if (__pickingEnabled)
+                                       pickingEnabled = true;
+                       }
+                       void disablePicking() { pickingEnabled = false; }
+                       bool isPickingEnabled() const { return 
pickingEnabled&&__pickingEnabled; }
+                       void resetPicking() { pickedTri = -1; }
+                       void __setPicking(bool flag) { __pickingEnabled = 
flag; }
+
+               private:                
                        Real sample_alpha;
                        
                        // This method intersects a list of triangles with 
the ray.
-                       int intersectTrianglesTransparent(const Ray* ray, 
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist, 
void *userData, const RenderContext &context) const;
+                       int intersectTrianglesTransparent(const Ray* ray, 
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist, 
void *userData, const RenderContext &context, bool isFirst=false) const;
                        
                        // This method is called by the above method with a 
hansong ray.
                        void _intersect(const Ray* ray, RayPacket::Element 
&e, RayTriIntersectUserData &isectData, const RenderContext &context, float 
_minDist=-1, float _maxDist=-1) const;

Modified: branches/itanium2/fox/FMantaWindow.cc
==============================================================================
--- branches/itanium2/fox/FMantaWindow.cc       (original)
+++ branches/itanium2/fox/FMantaWindow.cc       Sat Oct 15 10:39:09 2005
@@ -15,6 +15,10 @@
 #include <Model/Cameras/FisheyeCamera.h>
 #include <Model/MiscObjects/CuttingPlane.h>
 
+#include <Model/Groups/KDTree.h>
+#include <Model/Groups/TransparentKDTree.h>
+using namespace Manta::Kdtree;
+
 #include <iostream>
 #include <sstream>
 
@@ -66,6 +70,9 @@
        // Cutting planes.
        FXMAPFUNC(SEL_LEFTBUTTONPRESS, FMantaImageFrame::ID_PIXEL_SELECT, 
FMantaWindow::onAddCuttingPlane ),
 
+       // Picking
+       FXMAPFUNC(SEL_RIGHTBUTTONPRESS, FMantaImageFrame::ID_PIXEL_SELECT, 
FMantaWindow::onPick ),
+
        // Other options.
        FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_EXTRA_OPTIONS, 
FMantaWindow::onExtraOptions )
 };
@@ -490,6 +497,45 @@
        }
        
        return 1;
+};
+
+long FMantaWindow::onPick( FXObject *sender, FXSelector key, void *data ) {
+
+       FXEvent *event = (FXEvent *)data;
+
+       std::cout << "Picking at: " << event->win_x << " " << event->win_y << 
std::endl;
+
+       manta_interface->addTransaction("Picking",
+               
Callback::create(this,&FMantaWindow::mantaPick,event->win_x,event->win_y));
+
+       return 1;
+}
+
+
+void FMantaWindow::mantaPick( int x, int y ) const {
+       extern TransparentKDTree * __global_transparent_kdtree; 
+       extern KDTree * __global_kdtree;
+
+       if (__global_transparent_kdtree == NULL) {
+               cerr << "don't have a model to pick on\n";
+       }
+
+       Point point;
+       Vector normal;
+
+       // Shoot a ray into the scene.
+       __global_transparent_kdtree->enablePicking();
+       __global_kdtree->enablePicking();
+       if (!__global_kdtree->isPickingEnabled())
+               cerr << "cannot enable picking\n";
+       int result = manta_frame->shootOneRay( x, y, point, normal );
+       if (result) {
+       } else {
+               __global_kdtree->resetPicking();
+               __global_transparent_kdtree->resetPicking();
+       }
+       __global_kdtree->disablePicking();
+       __global_transparent_kdtree->disablePicking();
 };
 
 long FMantaWindow::onNavigator( FXObject *sender, FXSelector key, void *data 
) {

Modified: branches/itanium2/fox/FMantaWindow.h
==============================================================================
--- branches/itanium2/fox/FMantaWindow.h        (original)
+++ branches/itanium2/fox/FMantaWindow.h        Sat Oct 15 10:39:09 2005
@@ -155,6 +155,7 @@
                long onTraverser      ( FXObject *sender, FXSelector key, 
void *data );
                long onTraverserText  ( FXObject *sender, FXSelector key, 
void *data );
                long onAddCuttingPlane( FXObject *sender, FXSelector key, 
void *data );
+               long onPick( FXObject *sender, FXSelector key, void *data );
                long onExtraOptions   ( FXObject *sender, FXSelector key, 
void *data );
                
                // Accessors.
@@ -186,6 +187,7 @@
                void mantaRemoveCuttingPlane() const;
                void mantaMoveCuttingPlane( Real amount ) const;
                void mantaFlipCuttingPlane() const;
+               void mantaPick( int x, int y ) const;
                
                // This method is called by the manta thread to change the 
rendering mode.
                void FMantaWindow::mantaSetSceneObject( Object *root_object_ 
) const;

Modified: branches/itanium2/fox/dm_demo.cc
==============================================================================
--- branches/itanium2/fox/dm_demo.cc    (original)
+++ branches/itanium2/fox/dm_demo.cc    Sat Oct 15 10:39:09 2005
@@ -180,6 +180,11 @@
 
//////////////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////////////////////////
 
+// XXX to be replaced!
+namespace fox_manta {
+TransparentKDTree *__global_transparent_kdtree = NULL; 
+KDTree *__global_kdtree = NULL; 
+}
 
 Scene* createDefaultScene();
 
@@ -346,6 +351,10 @@
                // Create a transparent kdtree.
                TransparentKDTree *transparent_kdtree = 
                        new TransparentKDTree( kdtree, new 
KDTreeCopyColorMaterial );
+
+               // XXX to be replaced
+               __global_transparent_kdtree = transparent_kdtree;
+               __global_kdtree = kdtree;
                
                // Create a new extra options dialog.
                manta_window.addExtraOptionsDialog( "Transparency",




  • [MANTA] r629 - in branches/itanium2: Model/Groups fox, hansong, 10/15/2005

Archive powered by MHonArc 2.6.16.

Top of page