Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1332 - in trunk: Interface Model/Groups Model/MiscObjects Model/Primitives scenes


Chronological Thread 
  • From: thiago@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1332 - in trunk: Interface Model/Groups Model/MiscObjects Model/Primitives scenes
  • Date: Wed, 11 Apr 2007 22:40:08 -0600 (MDT)

Author: thiago
Date: Wed Apr 11 22:40:03 2007
New Revision: 1332

Added:
   trunk/Interface/AccelerationStructure.h
   trunk/Interface/Clonable.h
   trunk/Interface/Interpolable.h
Modified:
   trunk/Interface/CMakeLists.txt
   trunk/Interface/Camera.h
   trunk/Interface/Material.h
   trunk/Interface/Object.h
   trunk/Interface/TexCoordMapper.h
   trunk/Interface/Texture.h
   trunk/Model/Groups/Group.cc
   trunk/Model/Groups/Group.h
   trunk/Model/MiscObjects/KeyFrameAnimation.cc
   trunk/Model/MiscObjects/KeyFrameAnimation.h
   trunk/Model/Primitives/Heightfield.cc
   trunk/Model/Primitives/Heightfield.h
   trunk/Model/Primitives/PrimitiveCommon.cc
   trunk/Model/Primitives/PrimitiveCommon.h
   trunk/Model/Primitives/Triangle.cc
   trunk/Model/Primitives/Triangle.h
   trunk/scenes/primtest.cc
Log:
Added infrastructure for animations. In particular, added a clone and
interpolate interface classes which most things (Objects, Materials,
etc...) inherit from. Right now very few things actually have code
written to do the cloning and interpolating, so if for instance you
want a camera that can interpolate, you'll need to write that.
I still need to figure out how to add support for parallelizing the
interpolation, so it's possible the Interpolable interface might still 
change...

scenes/primtest.cc: 
   Modified to show linear interpolation for ply scene.

Interface/Material.h
Interface/Camera.h
Interface/Texture.h
Interface/Object.h
Interface/TexCoordMapper.h:
   These all inherit from Clonable and Interpolable. However, calling
   clone and interpolate on these classes will do nothing until someone
   implements those functions.

Interface/Clonable.h
Interface/Interpolable.h:
   These should be made into abstract base classes once all the
   classes that directly derive from these have their own versions of
   these functions.

Interface/AccelerationStructure.h:
   All acceleration structures should derive from this. This is currently
   required by the KeyFrameAnimation class.

Model/Groups/Group.h
Model/Groups/Group.cc
Model/Primitives/Heightfield.h
Model/Primitives/Heightfield.cc
Model/Primitives/Triangle.cc
Model/Primitives/Triangle.h
Model/Primitives/PrimitiveCommon.cc
Model/Primitives/PrimitiveCommon.h:
   Implemented clone and interpolate for these classes.

Model/MiscObjects/KeyFrameAnimation.cc
Model/MiscObjects/KeyFrameAnimation.h:
   Made some major changes from before. It now has working linear
   interpolation and can contain an acceleration structure.
  


Added: trunk/Interface/AccelerationStructure.h
==============================================================================
--- (empty file)
+++ trunk/Interface/AccelerationStructure.h     Wed Apr 11 22:40:03 2007
@@ -0,0 +1,19 @@
+#ifndef Manta_Interface_AccelerationStructure_h
+#define Manta_Interface_AccelerationStructure_h
+
+#include <Interface/Object.h>
+#include <Model/Groups/Group.h>
+
+namespace Manta {
+  class AccelerationStructure : public Object {
+  public:
+
+    //TODO: decide whether we want a seperate rebuild and update
+    //function or let the acceleration structure decide which to use.
+
+    virtual void rebuild(Group *group, int proc, int numProcs) = 0;
+    //virtual void update() = 0;
+
+  };
+}
+#endif //Manta_Interface_AccelerationStructure_h

Modified: trunk/Interface/CMakeLists.txt
==============================================================================
--- trunk/Interface/CMakeLists.txt      (original)
+++ trunk/Interface/CMakeLists.txt      Wed Apr 11 22:40:03 2007
@@ -2,12 +2,14 @@
 ADD_LIBRARY(Manta_Interface
         AmbientLight.h
         AmbientLight.cc
+        AccelerationStructure.h
         Background.h
         Background.cc
         Camera.h
         Camera.cc
        CameraPath.h
        CameraPath.cc
+        Clonable.h
         Context.h
         Fragment.h
         IdleMode.h
@@ -18,6 +20,7 @@
         ImageDisplay.cc
         ImageTraverser.h
         ImageTraverser.cc
+        Interpolable.h
         Light.h
         Light.cc
         LightSet.h

Modified: trunk/Interface/Camera.h
==============================================================================
--- trunk/Interface/Camera.h    (original)
+++ trunk/Interface/Camera.h    Wed Apr 11 22:40:03 2007
@@ -5,6 +5,7 @@
 #include <MantaTypes.h>
 #include <Core/Geometry/BBox.h>
 #include <Core/Geometry/AffineTransform.h>
+#include <Interface/Interpolable.h>
 
 #include <sgi_stl_warnings_off.h>
 #include <iosfwd>
@@ -36,7 +37,7 @@
     // want to store other parameters here.
   };
 
-  class Camera {
+  class Camera : public Interpolable {
   public:
     Camera();
     virtual ~Camera();

Added: trunk/Interface/Clonable.h
==============================================================================
--- (empty file)
+++ trunk/Interface/Clonable.h  Wed Apr 11 22:40:03 2007
@@ -0,0 +1,18 @@
+#ifndef Manta_Interface_Clonable_h
+#define Manta_Interface_Clonable_h
+
+namespace Manta {
+  class Clonable {
+  public:
+    enum CloneDepth {shallow //
+    };
+    virtual Clonable* clone(CloneDepth depth, Clonable* incoming=0)
+    {
+      if (incoming)
+        return incoming;
+      else
+        return this;
+    }
+  };
+}
+#endif //Manta_Interface_Clonable_h

Added: trunk/Interface/Interpolable.h
==============================================================================
--- (empty file)
+++ trunk/Interface/Interpolable.h      Wed Apr 11 22:40:03 2007
@@ -0,0 +1,28 @@
+#ifndef Manta_Interface_Interpolable_h
+#define Manta_Interface_Interpolable_h
+
+#include <Interface/Clonable.h>
+#include <vector>
+
+namespace Manta {
+  class Interpolable : public Clonable {
+  public:
+    enum InterpErr{success, 
+                   notInterpolable}; //cannot interpolate. No interpolation 
performed.
+
+    struct keyframe_t {
+      Interpolable* keyframe;
+      float t;
+    };
+
+    //Assuming the following operators existed, this function is
+    //supposed to do something like the following: 
+    //       *this = keyframe[0]*t[0] + ... + keyframe[n]*t[n];
+    //Make sure to check types of keyframes match
+    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes)
+    {
+      return notInterpolable;
+    }
+  };
+}
+#endif //Manta_Interface_Interpolable_h

Modified: trunk/Interface/Material.h
==============================================================================
--- trunk/Interface/Material.h  (original)
+++ trunk/Interface/Material.h  Wed Apr 11 22:40:03 2007
@@ -30,12 +30,14 @@
   DEALINGS IN THE SOFTWARE.
 */
 
+#include <Interface/Interpolable.h>
+
 namespace Manta {
   class PreprocessContext;
   class RayPacket;
   class RenderContext;
 
-  class Material {
+  class Material : public Interpolable {
   public:
     Material();
     virtual ~Material();

Modified: trunk/Interface/Object.h
==============================================================================
--- trunk/Interface/Object.h    (original)
+++ trunk/Interface/Object.h    Wed Apr 11 22:40:03 2007
@@ -2,6 +2,8 @@
 #ifndef Manta_Interface_Object_h
 #define Manta_Interface_Object_h
 
+#include <Interface/Interpolable.h>
+
 namespace Manta {
 
   class BBox;
@@ -9,7 +11,7 @@
   class RayPacket;
   class RenderContext;
 
-  class Object {
+  class Object : public Interpolable {
   public:
     Object();
     virtual ~Object();

Modified: trunk/Interface/TexCoordMapper.h
==============================================================================
--- trunk/Interface/TexCoordMapper.h    (original)
+++ trunk/Interface/TexCoordMapper.h    Wed Apr 11 22:40:03 2007
@@ -2,11 +2,13 @@
 #ifndef Manta_Interface_TexCoordMapper_h
 #define Manta_Interface_TexCoordMapper_h
 
+#include <Interface/Interpolable.h>
+
 namespace Manta {
   class RayPacket;
   class RenderContext;
 
-  class TexCoordMapper {
+  class TexCoordMapper : public Interpolable {
   public:
     TexCoordMapper();
     virtual ~TexCoordMapper();

Modified: trunk/Interface/Texture.h
==============================================================================
--- trunk/Interface/Texture.h   (original)
+++ trunk/Interface/Texture.h   Wed Apr 11 22:40:03 2007
@@ -2,13 +2,14 @@
 #ifndef Manta_Interface_Texture_h
 #define Manta_Interface_Texture_h
 
+#include <Interface/Interpolable.h>
 #include <Interface/Packet.h>
 
 namespace Manta {
   class RayPacket;
   class RenderContext;
   template<typename ValueType>
-  class Texture {
+  class Texture : public Interpolable {
   public:
     Texture() {};
     virtual ~Texture() {};

Modified: trunk/Model/Groups/Group.cc
==============================================================================
--- trunk/Model/Groups/Group.cc (original)
+++ trunk/Model/Groups/Group.cc Wed Apr 11 22:40:03 2007
@@ -1,6 +1,7 @@
 
 #include <Model/Groups/Group.h>
 #include <SCIRun/Core/Util/Assert.h>
+#include <assert.h>
 
 using namespace Manta;
 
@@ -19,6 +20,47 @@
 
 Group::~Group()
 {
+}
+
+Group* Group::clone(CloneDepth depth, Clonable* incoming)
+{
+  Group *copy;
+  if (incoming)
+    copy = static_cast<Group*>(incoming);
+  else
+    copy = new Group();
+
+  for(vector<Object*>::iterator iter = objs.begin();
+      iter != objs.end(); ++iter) {
+    Object *obj = *iter;
+    copy->add(static_cast<Object*>(obj->clone(depth)));
+  }
+  return copy;
+}
+
+Interpolable::InterpErr Group::interpolate(const std::vector<keyframe_t> 
&group_keyframes)
+{
+  InterpErr worstError = success;
+  vector<keyframe_t> keyframes(group_keyframes);
+  
+  Group *groups[group_keyframes.size()];
+  for(int frame=0; frame < keyframes.size(); ++frame) {
+    Group *group = dynamic_cast<Group*>(group_keyframes[frame].keyframe);
+    if (group == NULL)
+      return notInterpolable;
+    groups[frame] = group;
+    assert(group->getSize() == getSize());
+  }
+
+  for (int i=0; i < objs.size(); ++i) {
+    for(int frame=0; frame < keyframes.size(); ++frame) {
+      keyframes[frame].keyframe = groups[frame]->get(i);
+    }
+    InterpErr retcode = objs[i]->interpolate(keyframes);
+    if (retcode != success)
+      worstError = retcode;
+  }
+  return worstError;
 }
 
 void Group::add(Object* obj)

Modified: trunk/Model/Groups/Group.h
==============================================================================
--- trunk/Model/Groups/Group.h  (original)
+++ trunk/Model/Groups/Group.h  Wed Apr 11 22:40:03 2007
@@ -45,6 +45,12 @@
     Group();
     virtual ~Group();
 
+#ifndef SWIG
+    virtual Group* clone(CloneDepth depth, Clonable* incoming=NULL);
+
+    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes);
+#endif
+
     void add(Object* obj);
     void set( int i, Object *obj );
     Object *get( int i );

Modified: trunk/Model/MiscObjects/KeyFrameAnimation.cc
==============================================================================
--- trunk/Model/MiscObjects/KeyFrameAnimation.cc        (original)
+++ trunk/Model/MiscObjects/KeyFrameAnimation.cc        Wed Apr 11 22:40:03 
2007
@@ -1,5 +1,9 @@
 #include "KeyFrameAnimation.h"
+#include <Interface/Context.h>
+#include <Interface/MantaInterface.h>
 #include <SCIRun/Core/Thread/Time.h>
+#include <Model/Interpolators/LinearInterpolation.h>
+
 #include <cmath>
 
 using namespace Manta;
@@ -7,7 +11,8 @@
 
 KeyFrameAnimation::KeyFrameAnimation(InterpolationMode interpolation) : 
   interpolation(interpolation), currGroup(NULL), spareGroup(NULL),
-  duration(1), currTime(0), paused(false), barrier("keyframe animation 
barrier")
+  duration(1), currTime(-1), paused(false), barrier("keyframe animation 
barrier"),
+  as(NULL), updateToCurrTime(false)
 {
 }
 
@@ -16,8 +21,22 @@
   delete spareGroup;
 }
 
+void KeyFrameAnimation::push_back(Group *objects)
+{
+  if (spareGroup == NULL && interpolation != truncate) {
+    spareGroup = objects->clone(shallow);
+    currGroup = spareGroup;
+  }
+  frames.push_back(objects);
+}
+
 void KeyFrameAnimation::setInterpolation(InterpolationMode mode)
 {
+  if (mode != truncate) {
+    if (spareGroup == NULL && !frames.empty())
+      spareGroup = frames[0]->clone(shallow);
+    currGroup = spareGroup;
+  }
   interpolation = mode;
 }
 
@@ -26,6 +45,13 @@
   startTime = SCIRun::Time::currentSeconds();
   paused = false;
   currGroup = NULL;
+
+  if (spareGroup == NULL && interpolation != truncate && !frames.empty()) {
+    spareGroup = frames[0]->clone(shallow);
+    currGroup = spareGroup;
+  }
+
+  setTime(0);
 }
 
 void KeyFrameAnimation::pauseAnimation()
@@ -42,52 +68,68 @@
   paused = false;
 }
 
-bool KeyFrameAnimation::getLatestFrame(Group *&group, int proc, int numProcs)
-{
-  float newTime = SCIRun::Time::currentSeconds() - startTime;
-  bool differentFrame = setTime(newTime, proc, numProcs);
-  getCurrGroup(group);
-  return differentFrame;
-}
-
-bool KeyFrameAnimation::setTime(float time, int proc, int numProcs)
+void KeyFrameAnimation::update(Temp_Callback context)
 {
-  if (frames.empty())
-    return true;
-
-  if (proc == 0) {
-    differentFrame = isDifferentFrame(time);
-
-    //let's assume the animation wraps at the end
-    //first we need to handle negative times
-    time += static_cast<int>(fabs(time)/duration+1) * duration;
-    //now we can safely do the wrapping
-    time = fmodf(time, duration);
-    currTime = time;
+  //only one thread can do serial code
+  if (context.proc == 0) {
+    if (updateToCurrTime) {
+      updateToCurrTime = false;
+      differentFrame = isDifferentFrame(newTime);
+      startTime = context.time - newTime;
+      currTime = newTime;
+      if (paused) {
+        pauseTime = startTime;
+      }
+    }
+    else if (paused) {
+      differentFrame = false;
+    }
+    else {
+      float newTime = wrapTime(context.time - startTime);
+      differentFrame = isDifferentFrame(newTime);
+      currTime = newTime;
+    }
   }
 
   //need to make sure proc 0 has updated the currTime.
   //a barrier is a little heavy for this, but it's cleaner code (and I'm 
lazy).
-  barrier.wait(numProcs);
+  barrier.wait(context.numProcs);
 
-  if (!differentFrame)
-    return false;
-
-  float frame = currTime/duration * frames.size();
+  if (differentFrame) {
+    float frame = currTime/duration * frames.size();
 
-  if (interpolation == linear) {
-    //do interpolation in parallel
-    //TODO: Do the actual linear interpolation!
-  }
-  else if (interpolation == truncate) {
-    currGroup = frames[(int) frame];
+    if (interpolation == linear) {
+      //do interpolation in parallel
+      //TODO: Do the actual linear interpolation!
+      int start = static_cast<int>(frame);
+      int end   = (start+1) % frames.size();
+      float t = frame - start;
+
+      assert(frames[start]->getSize() == frames[end]->getSize());
+      std::vector<keyframe_t> keyframes(2);
+      keyframes[0].keyframe = frames[start];
+      keyframes[0].t = 1-t;
+      keyframes[1].keyframe = frames[end];
+      keyframes[1].t = t;
+
+      if (context.proc == 0) {//TODO: Parallellize this!
+        InterpErr errCode = currGroup->interpolate(keyframes);
+        if (errCode != success)
+          printf("KeyFrameAnimation had trouble interpolating!\n");
+      }
+    }
+    else if (interpolation == truncate) {
+      if (context.proc == 0) //TODO: Parallellize this!
+        currGroup = frames[(int) frame];
+    }
+    if (as)
+      as->rebuild(currGroup, context.proc, context.numProcs);
   }
-  return true;
 }
 
-bool KeyFrameAnimation::isDifferentFrame(float time)
+float KeyFrameAnimation::wrapTime(float time) const
 {
-  if (currGroup == NULL) return true;
+  //TODO: add other wrapping modes.
 
   //let's assume the animation wraps at the end
   //first we need to handle negative times
@@ -95,12 +137,38 @@
   //now we can safely do the wrapping
   time = fmodf(time, duration);
 
+  return time;
+}
+
+bool KeyFrameAnimation::setTime(float time)
+{
+  updateToCurrTime = true;
+
+  if (frames.empty())
+    return true;
+
+  differentFrame = isDifferentFrame(time);
+
+  newTime = wrapTime(time);
+
+  if (!differentFrame)
+    return false;
+  else
+    return true;
+}
+
+bool KeyFrameAnimation::isDifferentFrame(float time) const
+{
+  if (currGroup == NULL) return true;
+
+  time = wrapTime(time);
+
   if (interpolation == linear)
     return time != currTime;
 
   if (interpolation == truncate) {
-    int i = time/duration * frames.size();
-    int j = currTime/duration * frames.size();
+    int i = static_cast<int>(time/duration * frames.size());
+    int j = static_cast<int>(currTime/duration * frames.size());
     return i != j;
   }
 
@@ -108,11 +176,35 @@
     return true;
 }
 
+void KeyFrameAnimation::temporaryUpdate(int proc, int numProcs, bool &)
+{
+  Temp_Callback context;
+  context.proc = proc;
+  context.numProcs = numProcs;
+  context.time = SCIRun::Time::currentSeconds();
+  update(context);
+}
+
+void KeyFrameAnimation::intersect(const RenderContext& context, RayPacket& 
rays) const
+{
+  if (as)
+    as->intersect(context, rays);
+  else
+    currGroup->intersect(context, rays);
+}
+
 void KeyFrameAnimation::preprocess(const PreprocessContext& context)
 {
   for (int i=0; i < frames.size(); ++i) {
     frames[i]->preprocess(context);
   }
+
+  if (as)
+    as->preprocess(context);
+
+  context.manta_interface->registerParallelAnimationCallback(
+    Callback::create(this, &KeyFrameAnimation::temporaryUpdate));
+
 }
 
 void KeyFrameAnimation::computeBounds(const PreprocessContext& context, 
BBox& bbox) const
@@ -121,4 +213,10 @@
     currGroup->computeBounds(context, bbox);
   else if (!frames.empty())
     frames[0]->computeBounds(context, bbox);
+}
+
+void KeyFrameAnimation::useAccelerationStructure(AccelerationStructure* _as)
+{
+  as = _as;
+  //XXX need to do some more stuff to make sure the switch happens cleanly...
 }

Modified: trunk/Model/MiscObjects/KeyFrameAnimation.h
==============================================================================
--- trunk/Model/MiscObjects/KeyFrameAnimation.h (original)
+++ trunk/Model/MiscObjects/KeyFrameAnimation.h Wed Apr 11 22:40:03 2007
@@ -1,20 +1,23 @@
 #ifndef KeyFrameAnimation_h
 #define KeyFrameAnimation_h
 
+#include <Interface/AccelerationStructure.h>
 #include <Model/Groups/Group.h>
 #include <SCIRun/Core/Thread/Barrier.h>
 
 namespace Manta {
-  class KeyFrameAnimation{
+  struct Temp_Callback {int proc, numProcs;
+    float time;};//temporary so I can get code to compile
+
+  class KeyFrameAnimation : public Object{
   public:
     enum InterpolationMode{truncate, linear};
 
     KeyFrameAnimation(InterpolationMode interpolation=truncate);
     ~KeyFrameAnimation();
 
-    void push_back(Group *objects) {
-      frames.push_back(objects);
-    }
+    //add a keyframe
+    void push_back(Group *objects);
     
     //number of seconds the animation takes from start to end
     void setDuration(float time) { duration = time; };
@@ -23,33 +26,40 @@
     void pauseAnimation();
     void resumeAnimation();
 
+    void temporaryUpdate(int proc, int numProcs, bool &); //this will be 
replaced by update
+    void update(Temp_Callback context);
+
     //set animation to a specific time (frame)
     //returns whether the frame is different from the previous frame.
-    //This will block waiting for all numProcs. 
-    bool setTime(float time, int proc, int numProcs);
+    bool setTime(float time);
 
     //get the time of the frame currently being worked on.
-    float getTime() { return currTime; }
-
-    //update to latest time and get the Group for that frame.
-    //returns whether the frame is different from the previous frame.
-    //This will block waiting for all numProcs. 
-    bool getLatestFrame(Group *&group, int proc, int numProcs);
+    float getTime() const { return currTime; }
 
     //get the group for the frame currently being worked on.
-    void getCurrGroup(Group *&group) {
+    void getCurrGroup(Group *&group) const {
       group = currGroup;
     }
 
-    bool isDifferentFrame(float time);
+    bool isDifferentFrame(float time) const;
 
     void setInterpolation(InterpolationMode mode);
 
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+
     void preprocess(const PreprocessContext& context);
 
     void computeBounds(const PreprocessContext& context, BBox& bbox) const;
 
+    //TODO: should we instead have a collection of acceleration structures?
+    void useAccelerationStructure(AccelerationStructure* as);
+
+    AccelerationStructure *as;
+
   private:
+    
+    float wrapTime(float time) const;
+
     InterpolationMode interpolation;
 
     Group *spareGroup;  //used for interpolated frame -- has already 
allocated memory.
@@ -60,7 +70,10 @@
     float currTime;
 
     double startTime;    //world time of animation start
-    double pauseTime;
+    double pauseTime;    //world time at pause
+
+    bool updateToCurrTime; //use user supplied time instead of system time
+    double newTime;        //the user supplied time, normalized to [0, 
duration].
 
     bool paused;
 

Modified: trunk/Model/Primitives/Heightfield.cc
==============================================================================
--- trunk/Model/Primitives/Heightfield.cc       (original)
+++ trunk/Model/Primitives/Heightfield.cc       Wed Apr 11 22:40:03 2007
@@ -4,10 +4,12 @@
 #include <Core/Geometry/BBox.h>
 #include <Core/Geometry/Vector.h>
 
+#include <limits>
 #include <sgi_stl_warnings_off.h>
 #include <fstream>
 #include <iostream>
 #include <sgi_stl_warnings_on.h>
+#include <assert.h>
 
 using namespace Manta;
 using namespace std;
@@ -62,11 +64,105 @@
   delete[] data;
 }
 
+Heightfield* Heightfield::clone(Clonable::CloneDepth depth, Clonable 
*incoming)
+{
+  Heightfield *h;
+  if (incoming)
+    h = static_cast<Heightfield*>(incoming);
+  else
+    h = new Heightfield();
+
+  h->PrimitiveCommon::clone(depth, h);
+
+  h->m_Box = m_Box;
+  h->nx = nx;
+  h->ny = ny;
+  h->diag = diag;
+  h->cellsize = cellsize;
+  h->inv_cellsize = inv_cellsize;
+
+  h->data = new float*[nx+1];
+  float* p = new float[(nx+1)*(ny+1)];
+  for(int i=0;i<=nx;i++)
+    h->data[i] = p+i*(ny+1);
+
+  return h;
+}
+
+Interpolable::InterpErr 
+Heightfield::interpolate(const std::vector<keyframe_t> &keyframes)
+{
+  //TODO: Parallelize this
+  assert(!keyframes.empty());
+
+//   if (proc == 0) {
+
+
+  PrimitiveCommon::interpolate(keyframes);
+
+  Heightfield *heightfields[keyframes.size()];
+
+  for (int frame=0; frame < keyframes.size(); ++frame) {
+    Heightfield *h = dynamic_cast<Heightfield*>(keyframes[frame].keyframe);
+    if (h == NULL)
+      return notInterpolable;
+    heightfields[frame] = h;
+
+    if (frame>0) {
+      assert(h->nx == heightfields[0]->nx);
+      assert(h->ny == heightfields[0]->ny);
+    }
+  }
+
+  if (nx != heightfields[0]->nx || ny != heightfields[0]->ny) {
+    for (int i=0; i<=nx; ++i)
+      delete data[i];
+    delete[] data;
+    
+    nx = heightfields[0]->nx;
+    ny = heightfields[0]->ny;
+
+    data = new float*[nx+1];
+    float* p = new float[(nx+1)*(ny+1)];
+    for(int i=0;i<=nx;i++)
+      data[i] = p+i*(ny+1);
+  }
+
+  float minz = std::numeric_limits<float>::max(),
+        maxz = -std::numeric_limits<float>::max();
+
+    for (int i = 0; i <= nx; ++i)
+      for (int j = 0; j <= ny; ++j) {
+        float val = 0;
+        //lets hope this loop gets unrolled!
+        for (int frame=0; frame < keyframes.size(); ++frame) {
+          val += keyframes[frame].t * heightfields[frame]->data[i][j]; 
+        }
+        data[i][j] = val;
+        minz = min(data[i][j], minz);
+        maxz = max(data[i][j], maxz);
+      }
+
+    float dz = maxz-minz;
+    if(dz < 1.e-3)
+      dz = 1.e-3;
+
+    m_Box = BBox( Vector(m_Box.getMin().x(), m_Box.getMin().y(), 
minz-dz*1.e-4),
+                  Vector(m_Box.getMax().x(), m_Box.getMax().y(), 
maxz+dz*1.e-4));
+
+    // Step 1
+    diag = m_Box.diagonal();
+    cellsize = diag/Vector(nx, ny, 1);
+    inv_cellsize = cellsize.inverse();
+
+    return success;
+}
+
+
 void Heightfield::computeBounds(const PreprocessContext& /*context*/,
                                 BBox & bbox) const
 {
-  bbox.extendByPoint(m_Box.getMin());
-  bbox.extendByPoint(m_Box.getMax());
+  bbox.extendByBox(m_Box);
 }
 
 
@@ -230,8 +326,8 @@
   rays.computeHitPositions();
   
   for (int rayIndex=rays.begin(); rayIndex<rays.end(); rayIndex++) {
-    int Lx = rays.scratchpad<Vector>(rayIndex).x();
-    int Ly = rays.scratchpad<Vector>(rayIndex).y();
+    int Lx = (int)rays.scratchpad<Vector>(rayIndex).x();
+    int Ly = (int)rays.scratchpad<Vector>(rayIndex).y();
     Vector C = m_Box.getMin() + Vector(Lx, Ly, 0)*cellsize;
     Real u = (rays.getHitPosition(rayIndex).x()-C.x())*inv_cellsize.x();
     Real v = (rays.getHitPosition(rayIndex).y()-C.y())*inv_cellsize.y();
@@ -277,47 +373,4 @@
 //   for(i=0; i<=m_Nx; i++)
 //     for(j=0; j<=m_Ny; j++)
 //       m_Data[i][j] = ((m_Data[i][j] - min) * factor) + 
(m_Box.getMin().z() + margin);
-// }
-
-
-// // 
--------------------------------------------------------------------------------------
-// // --- Read the given file and returns nx, ny and the data
-// // 
--------------------------------------------------------------------------------------
-// void Heightfield::readHeightfieldFile(const char *fileName, unsigned int 
* pnx, unsigned int * pny, Real *** pdata)
-// {
-//   Real minz, maxz;
-//   int nx, ny, i, j;
-//   float ** data;
-
-//   ifstream in(fileName, std::ios::in | std::ios::binary);
-//   if (!in)
-//   {
-//     cerr << "Error : unable to open " << fileName << "\n";
-//     exit(1);
-//   }
-
-//   in >> nx >> ny >> minz >> maxz;
-//   if (!in)
-//   {
-//     cerr << "Error : unable to read header from " << fileName << "\n";
-//     exit(1);
-//   }
-//   in.get();
-
-//   ALLOCATE2DARRAY(data, nx+1, ny+1, float);
-//   in.read((char *)data[0], sizeof(float)*(nx+1)*(ny+1));
-//   if (!in)
-//   {
-//     cerr << "Error : unable to read data from " << fileName << "\n";
-//     exit(1);
-//   }
-
-//   *pnx = nx;
-//   *pny = ny;
-//   ALLOCATE2DARRAY(*pdata, nx+1, ny+1, Real);
-//   for(i=0; i<=nx; i++)
-//     for(j=0; j<=ny; j++)
-//       (*pdata)[i][j] = (Real)data[i][j];
-
-//   //  DELETE2DARRAY(data, nx+1);
 // }

Modified: trunk/Model/Primitives/Heightfield.h
==============================================================================
--- trunk/Model/Primitives/Heightfield.h        (original)
+++ trunk/Model/Primitives/Heightfield.h        Wed Apr 11 22:40:03 2007
@@ -5,7 +5,8 @@
 #include <Model/Primitives/PrimitiveCommon.h>
 #include <Core/Geometry/Vector.h>
 #include <Core/Geometry/BBox.h>
-
+#include <Model/MiscObjects/KeyFrameAnimation.h>
+#include <Interface/Clonable.h>
 namespace Manta {
 
   class Heightfield : public PrimitiveCommon
@@ -15,14 +16,18 @@
     Heightfield(Material *material, const std::string& filename, 
                 const Vector &minBound, const Vector &maxBound //, Real 
scale = 0.95);
                 );
+
     virtual ~Heightfield();
 
+    virtual Heightfield* clone(Clonable::CloneDepth depth, Clonable 
*incoming);
+
     virtual void computeBounds(const PreprocessContext & context, BBox & 
bbox) const;
     virtual void intersect(const RenderContext& context, RayPacket& rays) 
const;
     virtual void computeNormal(const RenderContext & context, RayPacket & 
rays) const;
 
 //     virtual void rescaleDataHeight(Real scale);
-//     virtual void readHeightfieldFile(const char *fileName, unsigned int * 
pnx, unsigned int * pny, Real *** pdata);
+
+    Interpolable::InterpErr interpolate(const std::vector<keyframe_t> 
&keyframes);
 
   private:
     BBox m_Box;
@@ -32,9 +37,7 @@
     Vector cellsize;
     Vector inv_cellsize;
 
-    struct HitData {
-      int x, y;
-    };
+    Heightfield() { };
 
   };
 }

Modified: trunk/Model/Primitives/PrimitiveCommon.cc
==============================================================================
--- trunk/Model/Primitives/PrimitiveCommon.cc   (original)
+++ trunk/Model/Primitives/PrimitiveCommon.cc   Wed Apr 11 22:40:03 2007
@@ -2,6 +2,7 @@
 #include <Model/Primitives/PrimitiveCommon.h>
 #include <Interface/Material.h>
 #include <Model/TexCoordMappers/UniformMapper.h>
+#include <assert.h>
 
 using namespace Manta;
 
@@ -19,6 +20,17 @@
 {
 }
 
+PrimitiveCommon* PrimitiveCommon::clone(CloneDepth depth, Clonable* incoming)
+{
+  PrimitiveCommon *copy;
+  assert (incoming); //PrimitiveCommon is an abstract base class, can't new 
it.
+  copy = static_cast<PrimitiveCommon*>(incoming);
+  copy->material = material;
+  copy->tex = tex;
+  
+  return copy;
+}
+
 void PrimitiveCommon::preprocess(const PreprocessContext& context)
 {
   material->preprocess(context);
@@ -29,3 +41,30 @@
   tex = new_tex;
 }
 
+Interpolable::InterpErr 
+PrimitiveCommon::interpolate(const std::vector<Interpolable::keyframe_t> 
&keyframes)
+{
+  //don't know how to interpolate between two materials, so lets
+  //do nearest neighbor.

+
+  float maxT=-1;
+  int maxTindex=-1;
+  for (int frame=0; frame < keyframes.size(); ++frame) {
+    if (keyframes[frame].t > maxT) {
+      maxT = keyframes[frame].t;
+      maxTindex = frame;
+    }
+  }
+  if (maxTindex < 0)
+    return notInterpolable;
+  
+  PrimitiveCommon *pc = 
dynamic_cast<PrimitiveCommon*>(keyframes[maxTindex].keyframe);
+  if (pc == NULL)
+    return notInterpolable;
+
+  material = pc->material;
+  tex = pc->tex;
+
+  return success;
+}

Modified: trunk/Model/Primitives/PrimitiveCommon.h
==============================================================================
--- trunk/Model/Primitives/PrimitiveCommon.h    (original)
+++ trunk/Model/Primitives/PrimitiveCommon.h    Wed Apr 11 22:40:03 2007
@@ -2,6 +2,7 @@
 #ifndef Manta_Model_PrimitiveCommon_h
 #define Manta_Model_PrimitiveCommon_h
 
+#include <Interface/Interpolable.h>
 #include <Interface/Primitive.h>
 
 namespace Manta {
@@ -23,6 +24,11 @@
 
     void setMaterial( Material *material_ ) { material = material_; }
     Material *getMaterial() const { return material; }
+
+#ifndef SWIG
+    virtual PrimitiveCommon* clone(CloneDepth depth, Clonable* 
incoming=NULL);
+    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes);
+#endif
 
   private:
     Material* material;

Modified: trunk/Model/Primitives/Triangle.cc
==============================================================================
--- trunk/Model/Primitives/Triangle.cc  (original)
+++ trunk/Model/Primitives/Triangle.cc  Wed Apr 11 22:40:03 2007
@@ -23,6 +23,21 @@
 {
 }
 
+Triangle* Triangle::clone(CloneDepth depth, Clonable* incoming)
+{
+  Triangle *copy;
+  if (incoming)
+    copy = static_cast<Triangle*>(incoming);
+  else
+    copy = new Triangle();
+
+  copy->PrimitiveCommon::clone(depth, copy);
+  copy->p1 = p1;
+  copy->p2 = p2;
+  copy->p3 = p3;
+  return copy;
+}
+
 void Triangle::computeBounds(const PreprocessContext&, BBox& bbox) const
 {
   bbox.extendByPoint(p1);
@@ -81,4 +96,20 @@
     rays.setNormal(i, Cross((p2-p1),(p3-p1)));
 }
 
-
+Interpolable::InterpErr Triangle::interpolate(const std::vector<keyframe_t> 
&keyframes)
+{
+  PrimitiveCommon::interpolate(keyframes);
+  p1 = Vector(0,0,0);
+  p2 = Vector(0,0,0);
+  p3 = Vector(0,0,0);
+  for (int i=0; i < keyframes.size(); ++i) {
+    Interpolable::keyframe_t kt = keyframes[i];
+    Triangle *tri = dynamic_cast<Triangle*>(keyframes[i].keyframe);
+    if (tri == NULL)
+      return notInterpolable;
+    p1 += tri->p1 * keyframes[i].t;
+    p2 += tri->p2 * keyframes[i].t;
+    p3 += tri->p3 * keyframes[i].t;
+  }
+  return success;
+}

Modified: trunk/Model/Primitives/Triangle.h
==============================================================================
--- trunk/Model/Primitives/Triangle.h   (original)
+++ trunk/Model/Primitives/Triangle.h   Wed Apr 11 22:40:03 2007
@@ -14,16 +14,19 @@
       Real a,b;
     };
 
-               Triangle() {  };
+    Triangle() {  };
     Triangle(Material* mat,
              const Vector& _p1, const Vector& _p2, const Vector& _p3);
     virtual ~Triangle();
     
+    virtual Triangle* clone(CloneDepth depth, Clonable* incoming);
+
     virtual void computeBounds(const PreprocessContext& context,
                                BBox& bbox) const;
     virtual void intersect(const RenderContext& context, RayPacket& rays) 
const ;
     virtual void computeNormal(const RenderContext& context, RayPacket 
&rays) const;    
     
+    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes);
     Vector p1, p2, p3;
   };
 }

Modified: trunk/scenes/primtest.cc
==============================================================================
--- trunk/scenes/primtest.cc    (original)
+++ trunk/scenes/primtest.cc    Wed Apr 11 22:40:03 2007
@@ -12,6 +12,7 @@
 #include <Model/Backgrounds/ConstantBackground.h>
 #include <Model/MiscObjects/Difference.h>
 #include <Model/MiscObjects/Intersection.h>
+#include <Model/MiscObjects/KeyFrameAnimation.h>
 #include <Model/Groups/Group.h>
 #include <Model/Groups/DynBVH.h>
 #include <Model/Lights/PointLight.h>
@@ -358,8 +359,11 @@
     t.initWithScale(Vector(100, 100, 100));
     //t.initWithScale(Vector(1, 1, 1));
 
-    Grid *as= new Grid();
-    group->add(as);
+    KeyFrameAnimation *animation = new 
KeyFrameAnimation(KeyFrameAnimation::linear);
+    AccelerationStructure *as= new Grid();
+    group->add(animation);
+    animation->useAccelerationStructure(as);
+    animation->startAnimation();
 
     //delete group; group = new DynBVH();
 
@@ -373,32 +377,42 @@
     }
     */
 
+    AffineTransform t1;
+    t1.initWithScale(Vector(50, 50, 50));
+
+    AffineTransform t2;
+    t2.initWithScale(Vector(100, 100, 300));
+
+    AffineTransform t3;
+    t3.initWithScale(Vector(300, 100, 100));
+
+
     Group *frame = new Group;
     if (!readPlyFile(modelName, t, frame, 0, matl))
        printf("error loading or reading ply file: %s\n", modelName.c_str()); 
//would be better to throw an error.
 
     Group *frame2 = new Group;
     string modelName2 = 
"/usr/sci/data/Geometry/Stanford_Sculptures/bun_zipper_res2.ply";
-    if (!readPlyFile(modelName2, t, frame2, 0, matl))
+    if (!readPlyFile(modelName, t1, frame2, 0, matl))
        printf("error loading or reading ply file: %s\n", 
modelName2.c_str()); //would be better to throw an error.
 
     Group *frame3 = new Group;
     string modelName3 = 
"/usr/sci/data/Geometry/Stanford_Sculptures/bun_zipper_res3.ply";
-    if (!readPlyFile(modelName3, t, frame3, 0, matl))
+    if (!readPlyFile(modelName, t2, frame3, 0, matl))
        printf("error loading or reading ply file: %s\n", 
modelName3.c_str()); //would be better to throw an error.
 
     Group *frame4 = new Group;
     string modelName4 = 
"/usr/sci/data/Geometry/Stanford_Sculptures/bun_zipper_res4.ply";
-    if (!readPlyFile(modelName4, t, frame4, 0, matl))
+    if (!readPlyFile(modelName, t3, frame4, 0, matl))
        printf("error loading or reading ply file: %s\n", 
modelName4.c_str()); //would be better to throw an error.
 
 
-    as->animation.push_back(frame);
-    as->animation.push_back(frame2);
-    as->animation.push_back(frame3);
-    as->animation.push_back(frame4);
+    animation->push_back(frame);
+    animation->push_back(frame2);
+    animation->push_back(frame3);
+    animation->push_back(frame4);
 
-    as->animation.setDuration(2);
+    animation->setDuration(20);
 
 #endif //USE_PRIVATE_CODE
   } else if (primtype == "heightfield") {




  • [MANTA] r1332 - in trunk: Interface Model/Groups Model/MiscObjects Model/Primitives scenes, thiago, 04/11/2007

Archive powered by MHonArc 2.6.16.

Top of page