Loading...
Logo
Processing Forum
Hi all,

I'm a structural engineering master student work on a seismic evaluation of a temple structure in Portugal. For the evaluation, I have created a 3D block model of the structure and will use a discrete element code to analyze the behaviour of the structure under a variety of seismic (earthquake) records. The software that I will use for the analysis has the ability to produce snapshots of the structure at regular intervals which can then be put together to make a movie of the response. However, producing the images slows down the analysis. Furthermore, since the pictures are 2D images from a specified angle, there is no possibility to rotate and view the response from other angles without re-running the model (a process that would take 3 days of computer time).

I am now looking for an alternative method for creating a movie of the response of the structure. What I want is a very lightweight solution, where I can just bring in the block model which I have and then produce the animation by feeding in the location and the three principal axis of each block at regular intervals to produce the animation on the fly. The blocks are described as prisms with the top and bottom planes defining all of the vertices. Since the model is produced as text files, I can modify the output so that it can be read and understood by the animation code. The model is composed of about 180 blocks with 24 vertices per block (so 4320 vertices). The location and three unit vectors describing the block axis are produced by the program and I can write them out in a way that I want.

The main issue is that the quality of the animation should be decent. If the system is vector based and allows for scaling, that would be great. I would like to be able to rotate the model in real time with simple mouse dragging without too much lag or other issues.

I have seen processing used for some amazing things. I don't have any experience with it but I am willing to learn it if it is the right tool for this purpose. I have very limited time (in fact I am already very behind). That is why I wanted to ask the experts here so that I don't waste my time on something that will not work in the end.

I would be very thankful if some of the more experienced users could share their insight about this project and point me in the right direction. I am not sure if this is appropriate, but if you feel that there is another program or approach that is more appropriate for this task, I would love to hear about that as well.

Thanks,
Ali

Replies(12)

Ok Ali,
I'm in on advising on some 3d things.
I joined the forum for the first time yesterday, so I'm sort of new. I've worked successfully with 3d in other contexts though. But .. don't expect me to do all the code for you. I cannot imagine, that it will come for free .. but then again .. processing is an amazing coding tool for newbies.
First of all .. go look at the 3d-libraries if you haven't been there already.
As for the speed of the expected final animation I cannot tell .. it probably depends on,particular issues that we can look into later. 
I'll assume that you have the deformation-algorithms'separated' on their own. How much time does it take to calculate 'a frame' .. one step of deformation? .. 
3d Animation of the vectors traditionally happens via 4*4 matrices .. translation, sheering, rotation and such are fairly easily expressed in matrices. Two more matrices goes into the process: one connected to the concept of 'a camera', and one that does the perspective.
The camera-matrix will be dynamic (with mouse-input) .. 

I'm not sure how the 3d library will deal with shielding off planes that lies behind other planes and thus doesn't need to be drawn, but it's probably handled.
.. 
I'll look into the forum now and then and respond to your feedback.

Carsten


Hey Carsten,

Thank you for your reply. Well I've been trying to understand how this might be done in Processing. I've started with trying to create the blocks first. I've got something working but I'm having problems with displaying the block object and zooming in and rotating the display.

Copy code
  1. // Display settings
    float angleInc;
    float rotX = 0.0, rotY = 0.0;
    int lastX, lastY;
    float distX = 0.0, distY = 0.0;

    // Blocks
    Block block1;
    ArrayList topvert;
    ArrayList botvert;

    void setup() {
      size(640, 360, P3D);
      noStroke();
      angleInc = PI/300.0;
     
      topvert = new ArrayList();
      topvert.add(new PVector(  -8.320,  12.186,   3.583));
      topvert.add(new PVector(  -8.464,  12.330,   3.583));
      topvert.add(new PVector(  -8.661,  12.383,   3.583));
      topvert.add(new PVector(  -8.859,  12.330,   3.583));
      topvert.add(new PVector(  -9.003,  12.186,   3.583));
      topvert.add(new PVector(  -9.056,  11.989,   3.583));
      topvert.add(new PVector(  -9.003,  11.791,   3.583));
      topvert.add(new PVector(  -8.859,  11.647,   3.583));
      topvert.add(new PVector(  -8.661,  11.594,   3.583));
      topvert.add(new PVector(  -8.464,  11.647,   3.583));
      topvert.add(new PVector(  -8.464,  11.647,   3.583));
      topvert.add(new PVector(  -8.267,  11.989,   3.583));
     
      botvert = new ArrayList();
      botvert.add(new PVector(  -8.315,  12.184,   4.811));
      botvert.add(new PVector(  -8.458,  12.327,   4.811));
      botvert.add(new PVector(  -8.654,  12.379,   4.811));
      botvert.add(new PVector(  -8.849,  12.327,   4.811));
      botvert.add(new PVector(  -8.992,  12.184,   4.811));
      botvert.add(new PVector(  -9.045,  11.989,   4.811));
      botvert.add(new PVector(  -8.992,  11.793,   4.811));
      botvert.add(new PVector(  -8.849,  11.650,   4.811));
      botvert.add(new PVector(  -8.654,  11.598,   4.811));
      botvert.add(new PVector(  -8.458,  11.650,   4.811));
      botvert.add(new PVector(  -8.315,  11.793,   4.811));
      botvert.add(new PVector(  -8.263,  11.989,   4.811));
     
      // initialize vertex arrays
      block1 = new Block(topvert, botvert);
    }

    void draw(){
      background(170, 95, 95);
      lights();
      fill(255, 200, 200);
      //translate(width/2, height/2);
      //rotateX(frameCount * angleInc);
      //rotateY(frameCount * angleInc);
      //rotateZ(frameCount * angleInc);
     
      translate(width/2, height/40);
      rotateX(rotX + distY);
      rotateY(rotY + distX);
     
      //translate(width/2, height/10);
      scale(20, 20, 20);
     
      // Draw the block
      block1.display();
    }

    void mousePressed(){
      lastX = mouseX;
      lastY = mouseY;
    }

    void mouseDragged(){
      distX = radians(mouseX - lastX);
      distY = radians(lastY - mouseY);
    }

    void mouseReleased(){
      rotX += distY;
      rotY += distX;
      distX = distY = 0.0;
    }

    class Block {
     
      PVector vertices[][];
      int vcount;
      PVector centroid[];
      PVector axes[][];
     
      Block(ArrayList topvertices, ArrayList botvertices) {
       
        if (botvertices.size() != topvertices.size()) {
          //
        } else {
          // Get the total number of vertices
          vcount = topvertices.size() + botvertices.size();
          println(vcount);
         
          // Initialize the list of vertices
          vertices = new PVector[2][(vcount / 2) + 1];
         
          // Extract the vertices
          for(int i = 0; i < (vcount / 2); i++){
            vertices[0][i] = (PVector) botvertices.get(i);
            vertices[1][i] = (PVector) topvertices.get(i);
          }
         
          //Add the first vertices to the end to close block
          vertices[0][vcount / 2] = (PVector) botvertices.get(0);
          vertices[1][vcount / 2] = (PVector) topvertices.get(0);
         
        }
      }
     
      void display() {
        // Draw the sides
        beginShape(TRIANGLE_STRIP);
        for (int j = 0; j <= (vcount / 2); j++) {
          vertex(vertices[0][j].x, vertices[0][j].y, vertices[0][j].z);
          vertex(vertices[1][j].x, vertices[1][j].y, vertices[1][j].z);
        }
        endShape();
       
        // Draw the caps
        for (int i = 0; i < 2; i++) {
          beginShape();
          for (int j = 0; j <= (vcount / 2); j++) {
            vertex(vertices[i][j].x, vertices[i][j].y, vertices[i][j].z);
          }
          endShape();
        }
      }
     
      void move(PVector newposition, float scalefactor) {
        //
      }
     
      void rotate(PVector newaxes, float scalefactor) {
        //
      }
     
      void transform(PVector newposition, PVector newaxes) {
        transform(newposition, newaxes, 1.0);
      }
     
      void transform(PVector newposition, PVector newaxes, float scalefactor) {
        // Transform the block
        rotate(newaxes, scalefactor);
        move(newposition, scalefactor);
      }
     
    }
Eventually I would like to just read the model file I have and extract the vertices and pass them to the object constructor. As you can see my original coordinate system is in meters and I'm having problem getting the display to work. I'm trying to understand this at the moment. But I thought I should share what I've got and see if you've got any pointers.

Bests,
Ali
Hi Ali,
I'm looking at the code .. and I'm in a learning-position as to syntax and how the code accomplishes the geometric tasks. I tried it in the editor, and it works! You cannt be much off then.

As to the rotation .. I think that the rotation strictly happens around the axis. If you want it to rotateY around itself you may have to .. translate the object-center onto the y axis, do rotationY and then translate back.

Test out your rotations by moving the mouse along one axis only (vertical/horizontal) and evaluate the outcome visually. That should give you a hit of what could be wrong.

About the meters input .. you've got the collective 'scale' to deal with that problem. 

There is no messing with four component vectors and multiplication of matrices as I was setting myself up to.

EDIT:
quarks has a point about the camera-thing in that the rotation you have accomplished has been on the object that you look at, and not at the point that you look from .. and that's eventually where you want it, even if it doesn't look any different right now.


You might try the Shapes3D library for the actual prisms (could use a tube with 12 sides) and PeasyCam library to control the camera view.

Links to these libraries can be found here.

taking a look of your problem from afar


I am now looking for an alternative method for creating a movie of the response of the structure. What I want is a very lightweight solution, where I can just bring in the block model which I have and then produce the animation by feeding in the location and the three principal axis of each block at regular intervals to produce the animation on the fly.

hm...

shouldn't your other 3 day earthquake program deliver raw data for all blocks into a textfile which then processing can load and draw? Or even use 3ds or obj files here?

Thus you don't need any rotateX stuff but just draw the blocks either by drawing obj files or by using beginShape and
vertex(x, y, z);  or vertex(x, y, z, u, v);
http://www.processing.org/reference/beginShape_.html


And then use PeasyCam library of course.

Greetings, Chrisir




Chrisir,

This sounds like a good idea. As quarks also pointed out, I think I am reinventing the wheel here. Since I do have the actual 3D model in Rhino and can actually export it into obj or 3ds format, then it makes sense to bring those into processing. I've been messing about with peasycam for the past hour and I think it will work once I figure out how to work with it properly.

I guess the only thing that would then remain is to figure out how to read in the object displacement/rotation data at each time interval and actually transform each of the blocks to get a movie. Any thoughts about this? Are there libraries that already let me do all this?

Thank you guys for all the great ideas. I think this might actually work!

Regards,
Ali

yeah, there are great libraries around for exporting 3D models.

As I see it your other 3 day earthquake program deliver raw data for all blocks.

Since it's a movie it has frames. Let's say 26 frames per second and your movie is 1 minute so you have
26*60 frames / images in your movie.

So it delivers 26*60 files each with with lines (or 4320 vertices) or whatever.

You print the files and handle the cam separately e.g. with the code below


how to read in the object displacement/rotation data at each time interval and actually transform each of the blocks to get a movie.

can't you read the  26*60 files in an array and push the frames to the screen one after another?

Thus you don't need "transform each of the blocks"




Copy code
  1. import shapes3d.utils.*;
  2. import shapes3d.org.apache.commons.math.util.*;
  3. import shapes3d.org.apache.commons.math.*;
  4. import shapes3d.org.apache.commons.math.geometry.*;
  5. import shapes3d.*;
  6. // =========================================================================
  7. // Lamppost
  8. int ZentraleStange_XValue = 250; // nach rechts
  9. int ZentraleStange_YValue = 330; // nach unten
  10. int ZentraleStange_ZValue = -150; // nach hinten
  11. // Lamppost
  12. int TiefeQuerbalken = 122;
  13. // hanging basket
  14. int HoeheEinesBlumenkastens = 20;
  15. int TiefeEinesBlumenkastens = 122;
  16. int BreiteEinesBlumenkastens = 50;
  17. //  hanging basket
  18. Cone cone;
  19. Ellipsoid [] ellipsoid = new Ellipsoid [4];
  20. String actualTextMessage = "Use 0,1,2,3 for Camera";
  21. String actualTextMessage2 = "Camera circles at constant height";
  22. // ==================================================================
  23. // Kamerasteuerung:
  24. final int CheckCamera_Type_SinusLevel = 0;    // rotates
  25. final int CheckCamera_Type_SinusSpirale = 1;  // Spirale
  26. final int CheckCamera_Type_SinusMouse = 2;    // Mouse
  27. final int CheckCamera_Type_SinusPath = 3;     // Path
  28. float Angle = 0.0; // Angle bei Kreis
  29. float Height = 330;    // Höhe der Kamera über der Szene
  30. int HeightAdd = 2;   // wird bei Spirale zu der Höhe der Kamera addiert
  31. float Radius = 110.0;  // Anfangsradius des Kreises
  32. // Art des Kameraverhaltens
  33. int CheckCamera_Type = CheckCamera_Type_SinusSpirale;
  34. // Camera
  35. int LookAtX;
  36. int LookAtY;
  37. int LookAtZ;
  38. // Camera with Path Behaviour (CheckCamera_Type = 3)
  39. boolean boolGoesOnAPath = true;
  40. float PathValue;
  41. float PathValueMaximal = 95.0;
  42. // ==========================================================
  43. void setup() {
  44.   size(600, 600, P3D);
  45.   // Grass
  46.   //  initGrass();
  47.   // LookAt
  48.   LookAtX=ZentraleStange_XValue;
  49.   LookAtY= ZentraleStange_YValue;
  50.   LookAtZ= ZentraleStange_ZValue;
  51.   // hanging baskets
  52.   for (int i = 0; i < ellipsoid.length; i = i+1) {
  53.     ellipsoid[i] = new Ellipsoid(this, 40, 40);
  54.     ellipsoid[i].drawMode(Shape3D.SOLID);
  55.     ellipsoid[i].setRadius(12, 7, 12);
  56.     ellipsoid[i].moveTo(ZentraleStange_XValue, ZentraleStange_YValue+40, ZentraleStange_ZValue-(TiefeQuerbalken/2)+5);
  57.   }
  58.   ellipsoid[0].moveTo(ZentraleStange_XValue, ZentraleStange_YValue+40, ZentraleStange_ZValue-(TiefeQuerbalken/2)-1);
  59.   ellipsoid[1].moveTo(ZentraleStange_XValue, ZentraleStange_YValue+40, ZentraleStange_ZValue+(TiefeQuerbalken/2)-1);
  60.   ellipsoid[2].moveTo(ZentraleStange_XValue-(TiefeQuerbalken/2)+0, ZentraleStange_YValue+40, ZentraleStange_ZValue); 
  61.   ellipsoid[3].moveTo(ZentraleStange_XValue+(TiefeQuerbalken/2)+0, ZentraleStange_YValue+40, ZentraleStange_ZValue);
  62. } // function
  63. void draw() {
  64.   background(153);
  65.   textMode(SCREEN);
  66.   fill(242);
  67.   //text(actualTextMessage + " (now: " + actualTextMessage2 + ").", 10, 30);
  68.   //CheckCamera();
  69.   CheckCameraSinusLevel();
  70.   //  Grass();
  71.   stroke(22);
  72.   PaintLamppost();
  73.   Angle=Angle+1.0;
  74.   if (boolGoesOnAPath) {
  75.     PathValue=PathValue+1;
  76.   }
  77.   PaintHangingBasket();
  78. }
  79. // =====================================================================
  80. void PaintHangingBasket () {
  81.   // Schleife!
  82.   for (int i = 0; i < ellipsoid.length; i = i+1) {
  83.     stroke(22);
  84.     // Blumenkasten
  85.     ellipsoid[i].fill(color(72, 66, 44));
  86.     ellipsoid[i].draw();
  87.     stroke(22);
  88.     // je zwei Drähte
  89.     line (ellipsoid[i].x()-10, ellipsoid[i].y(), ellipsoid[i].z(),
  90.     ellipsoid[i].x(), ellipsoid[i].y()-43, ellipsoid[i].z());
  91.     line (ellipsoid[i].x()+10, ellipsoid[i].y(), ellipsoid[i].z(),
  92.     ellipsoid[i].x(), ellipsoid[i].y()-43, ellipsoid[i].z());
  93.     // je drei Blumen
  94.     pushMatrix();
  95.     translate (ellipsoid[i].x(), ellipsoid[i].y()-17, ellipsoid[i].z());
  96.     scale(.2);
  97.     rotateY(.7);
  98.     //Flower(1, 1, +200, 17, 3);
  99.     popMatrix();
  100.     pushMatrix();
  101.     translate (ellipsoid[i].x()-2, ellipsoid[i].y()-17, ellipsoid[i].z()-2);
  102.     scale(.25);
  103.     rotateY(2*PI-.2); 
  104.     //Flower(1, 1, ellipsoid[i].x()-22, ellipsoid[i].y()+117, ellipsoid[i].z()-21);
  105.     popMatrix();
  106.     pushMatrix();
  107.     translate (ellipsoid[i].x()+2.2, ellipsoid[i].y()-17, ellipsoid[i].z()-2.3);
  108.     rotateY(1.32); 
  109.     scale(.23);
  110.     //Flower(1, 1, +2, 7, 221);
  111.     popMatrix();
  112.   } // for
  113. } // SR
  114. // =====================================================================
  115. void PaintLamppost () {
  116.   // http://en.wikipedia.org/wiki/Street_light
  117.   // central lamppost
  118.   pushMatrix();
  119.   int Hoehe = 220;
  120.   fill(190, 3, 3);
  121.   translate(ZentraleStange_XValue-0,
  122.   ZentraleStange_YValue+(Hoehe / 2),
  123.   ZentraleStange_ZValue-0);
  124.   rotateY(0.0);
  125.   box(11, Hoehe, 11);
  126.   popMatrix();
  127.   // Querbalken 1
  128.   pushMatrix();
  129.   fill(9, 3, 233);
  130.   translate(ZentraleStange_XValue,
  131.   ZentraleStange_YValue,
  132.   ZentraleStange_ZValue);
  133.   rotateY(0.0);
  134.   box(11, 11, TiefeQuerbalken);
  135.   popMatrix();
  136.   // Querbalken 2
  137.   pushMatrix();
  138.   fill(9, 9, 223);
  139.   translate(ZentraleStange_XValue,
  140.   ZentraleStange_YValue,
  141.   ZentraleStange_ZValue-0);
  142.   rotateY(radians(90.0));
  143.   box(11, 11, TiefeQuerbalken);
  144.   popMatrix();
  145. }
  146. void CheckCameraSinusLevel () {
  147.   // Rotates in "Height"
  148.   if (!keyPressed) {
  149.     // look to scene (center)
  150.     camera (
  151.     Radius*sin (radians(Angle)) + ZentraleStange_XValue, Height, Radius* cos (radians(Angle)) + ZentraleStange_ZValue,
  152.     ZentraleStange_XValue, ZentraleStange_YValue, ZentraleStange_ZValue,
  153.     0.0, 1.0, 0.0);
  154.   }
  155.   else {
  156.     // look ahead
  157.     camera (
  158.     Radius*3*sin (radians(Angle)) + ZentraleStange_XValue, Height, Radius* cos (radians(Angle)) + ZentraleStange_ZValue,
  159.     Radius*sin (radians(Angle+5)) + ZentraleStange_XValue, Height, Radius* cos (radians(Angle+5)) + ZentraleStange_ZValue,
  160.     0.0, 1.0, 0.0);
  161.   }
  162. }


Hi guys,

Well here is an update on where I am right now:
  1. I've got the model into processing successfully. I ended up writing my own object class (is that right? this type of stuff is new to me - I guess I should have paid attention in comp sci!). I was tempted to use the obj_importer to just bring the model in, but after looking at the output from Rhino, it seems the block faces are unnecessarily broken up when the .obj file is written. So I just make my own objects. I'm hoping this won't cause any performance issues.
  2. I am wrestling with my analysis software to get a proper set of information for block transformation. I wanted to follow Chrisir's idea of loading a new model for each frame. However, this would defeat the whole purpose of this exercise which is to eliminate the need for the analysis program to generate any output. Furthermore, the analysis program (at least the current version) can only write image files :( So I am stuck with doing the transformations myself in the code.
  3. I got the camera view working although I need to customize it a bit more.
My current wish list is as follows:
  1. Flip the model. I guess processing flips the coordinate system about the y axis. I haven't found any method of setting the coordinate system. I am hoping I don't have to reverse all the y-coordinates to get this working.
  2. Get an axis triad in the corner of the screen. I would like the axis to update its orientation but not scale or move with the camera. I think this helps to show the directions of the model and the direction of the applied earthquake.
  3. A tree of the model blocks (possibly separated into regions). I'm thinking this might be useful for showing/hiding blocks and regions (defined in the model file for each column or architrave).
  4. I wouldn't mind also having the ability to manipulate block properties using clicking (mainly visibility).
My biggest question right now, however, is how to do the transformations. There are two scenarios:
  1. The program can give me the location of the centroid and the orientation of the principal axes at each step. Then I have to use this information to transform the vertices. Any ideas about how this is done? Any example algorithms?
  2. The program can't give me the orientation of the principal axes (looking more likely) and I have to instead use displacement (3 components) values of vertices on each block to calculate the displacement of the rest of the vertices. My thought was that you only need two points on the rigid block to be able to calculate the position of the rest of the blocks. However, based on my short reading (on Wikipedia :p) apparently you need at least 3 non-collinear points. I think any set of 3 vertices will work since they all form a plane. Does anyone have any idea how this can be done?
I actually like the second method more since one of the things I would also like to do is to be able to magnify the response for smaller earthquakes. If I use the centroid position and orientation, I will be dealing with big numbers and to magnify the response I need to back-calculate the block displacements which are small numbers (generally). So accuracy suffers greatly in the process.

I'm sorry for the long post. This is a challenging project, especially for an idiot like me! Any and all help is much appreciated.

Regards,
Ali

PS: I don't know how to put my files here so I've uploaded my sketch so far to here.
hi Ali,
 Furthermore, the analysis program (at least the current version) can only write image files
That is a problem. If you don't have access to calculated results .. you've got nothing to use the program for. Does it give an output of the block-position at time t, or are the block-data a one-time input only? If you get position data then you can calculate what happened between t1 & t2.
[these issues are addressed further down]

Flip the model. I guess processing flips the coordinate system about the y axis. I haven't found any method of setting the coordinate system. I am hoping I don't have to reverse all the y-coordinates to get this working
 
Ok, here goes the long explanation: Vertices are vectors (position and sometimes orientation). Vectors are changed by matrices. Every change is infront or behind the screen performed by matrices. A whole set of matrices are added and multiplied together into one matrix that then is set to work on the vector/vertex once for each frame (frame-of-reference .. I think the term was born in this kind of thinking).
Traditionally you should think in terms of object-, world-, camera-,and projection-space. You start out with an object vector that can be delt with relative to the other vectors in the object. Object-space is where you have two objects of the same kind (same class) .. one round .. the other worked upon by an object-matrix and flattened a bit. The important 'space' is the world-space [see edited note below].. that's where you want things to happen. It's represented by a matrix too .. an identity-one of the kind to start with. Numeric changes of this matrix expresses different types of changes (translation, sheering, rotation and such). The world-matrix is set to work on all vectors in the world, hence the name. You could think of it as working on the coordinate-system that your objects are put into. So, it could be the world-matrix you need to 'flip' .. unless it's just a question of looking at the world from 180 degrees around the y-axis .. that's where the camera-matrix lives. And one of different types of projection is applied last.
You have noted that writing Translate( parameters ) moves stuff. Depending of the space .... the same translation has different outcome depending on what it works on (on an object, the whole set world or the camera)

Does this enable you to figure out what should be done about the 'flipping'?

As for the constant camera-interdependent triade ... "  I think this helps to show the directions of the model and the direction of the applied earthquake"
 .. it's not going to do anything specifically until you know exactly what you want it to show.


A tree of the model blocks (possibly separated into regions)  
I cannot tell weather such an object is available (like a linked list). I figured that you might need it if you have to deal with boundary-conditions for each block. If you venture into writing your own, then ... once it gets messy, remember: CODING IS FUN!
We can get back to it later.


The program can give me the location of the centroid and the orientation of the principal axes at each step
 
Well .. that's really something. That IS the info you need, except that it's the vector-properties after matrix-manipulation where it's the matrix we want. It's an object-matrix in the sense of my writing above. Each block only differs from each other by the individual properties of this matrix. Does individual blocks deform? If not, you can reconstruct the matrix.

Yes, you need three points. It's no big deal (apply dot and cross-product on the two vectors you can make out of the three points).[ If the direction is normalized, then the dotproduct between v(1,0,0) and the direction-vector = cos(alfa), where alfa is the latitued of the direction .. (if memory serves me right)]

Accuracy usually is a major issue that sometimes forces the code to be somewhat clotted .. I don't know how the situation is in processing.

Last: I cann't figure out how to extract the .pde's from your link.


I hope something of this post helps clear things up.

Carsten

EDIT: note
Writing that the world-space is where 'things' happen is misleading as to the earthquake-deformations to the model. It happens in object-space: Each block-object has it's properties(position & orientation) changed. 
You start out saying that you've written your own object-class. That's exactly what comes to mind as desirable.. if you talk about the block-prism. The only differences between them is the parameter you are going to change in your animation anyway (position and direction). If you have worried about the necessity to draw each block individually ...I think you can stay worried. It can be put into a for loop though. With a 'unit' block in place, you can move the bookkeeping to their associated matrices.
I hope Chrisir and quark is following, to prevent me from leading you astray.
Hi Carsten,

You can download the entire sketch as a zip file by clicking File and then Download. You need the entire thing to be able to run the sketch.

I have managed to flip the image by just changing the sign on y-coordinates. I think this is just because processing uses a different y-direction than you normally use. I stumbled upon this in one of the tutorials. So now the model looks normal.

I am trying to figure out how to compute the location of the other vertices if I know the location of three vertices. I guess this is the essential question. Once I have a function for this, then I can just get the displacements of three points on each block and move the blocks in Processing. My analysis program is capable of outputting all the vertex displacements but this would create huge files which I think is unnecessary. I would rather do the calculations at run-time and than deal with huge text files. That is unless others disagree with this approach.

My comment earlier about .obj output was related to Chrisir's suggestion to have the program create a wavefront object file (a type of 3D file) at each step and just loading the files to create the animation. This again is a waste of disk space and slows the analysis (which is the only reason I am trying to write this visualization program in processing).

What I meant by the triad in the corner is something similar to what you get in CAD programs like AutoCAD. you have just two/three arrows which show you the directions of the coordinate system. In most programs it doesn't matter if you zoom or pan, the direction arrows stay in the same place. If you are in 3D, the axes rotate to reflect your view orientation. I hope this is more clear. I just want it so that I can correlate the direction of ground motion to the (which I had specified for the analysis) with what I see on the screen.

I hope that clears up some of the points.

I will keep you guys posted about my progress. If anyone has any ideas or suggestions, I am all ears.

Thanks for your help,
Ali
Hi cannibal
I got the .pde down, but I havn't got the peasy dependancy, so it won't run.

" I have managed to flip the image by just changing the sign on y-coordinates."
hm. You are brand new in 3D. Stay in processing becourse it desn't get any easier than here.
It's not unusual that the y-axis is pointing downwards. One pretty important detail is the 'orientation' of the coordinatesystem you choose .. you can chose between left or right-handed orientation of the axis. Put the tree first fingers (thumb + 2 more) on your right hand and position them as a coordinatesystem. If you can align the direction of the fingers (in xyz order) as pointing in the positive directions of the axis .. then it's a right handed system. ( Please do check out the correctness of my suggestions .. I'm often making mistakes).  I prefer a lefthanded becourse it points z into the screen, away from me. Some 3d libraries offers two sets of transforms .. one for left and one for right-handed; and other things like what side of a plan is up etc.

" I am trying to figure out how to compute the location of the other vertices if I know the location of three vertices."
That's a nice sort of problem becourse it calls on what you learned in school or can look up in your physics-book.
I have a problem visualizing the block-prism. How is the profile of the 'ring' of vertices making a top/bottom-face? Anyway .. if you take a cross-product of two vectors in that plane, you get a third vector that's perpendicular to both vectors (essentially pointing in the up-direction (that is y, right?). I sort of have to have an impression of how the points relates to each other on the top-face, to direct you to build z and x. 
I would like to reiterate this problem again... do you know the basic block from which shape all others have been moulded? That's another way of asking if you know the block in it's object-space. It looked like a cylinder ... if it is, then stack up the 24 vertices in a for loop ( for (int i = 0 ; i < 12 ; i++ ){new vertices and some cos & sin }) and build the block yourself.
You can then loop 4000 copies of that block into place by using the first set of data from your model (position and presumably a direction pointing straight up) .. and repeat and repeat. This approach requires a tiny bit of information: We have the centroide position and the up-vector direction ... but the block can have turned around that up-vector without changing the position of the center. Is there an implicit accept of zero turn or is the program simply hiding this bit of info? Well .. just an idea. We seem to have to have a look at those individual vectors anyhow, so .. is there two set of points that aligns up with x and z? If it's a circle of 12 points there ought to be. Use those vectors (from pairwise two points) and project them down (dot-product) on (1,0,0), (0,1,0),(0,0,1) and eventually find out the angle it  has turned from the unit vectors. These angles will go into a composit matrix and you'r home. First rotate and then translate. Done.
 

Morning Ali,
I had a look at the code, Nice work!

[look at the edits below before reading on]

I forgot to comment on the  triad .. such a thing is hard to do without.
The obvious thing is (1) to display it before you involve the camera. You instantiate a new camera  in Setup() and sets it's parameters too ( camera(0, 0, 50, 0, 0, 0, 0, 1, 0);) .. maybe this line sets it going. Try draw triade before setting the parameters. ( Recall that I havn't got practical experience in processing. )
Fount his in references:
beginCamera();
camera();
rotateX(-PI/6);
endCamera();



in your 'wishList:
  1. A tree of the model blocks (possibly separated into regions). I'm thinking this might be useful for showing/hiding blocks and regions (defined in the model file for each column or architrave).
I'll suggest that you group the different blocks for a region and collects these regions in an arraylist. Making a tree is overkill. Take a look at  HashMap  to see if it's convenient to you. 

---------
  1. I wouldn't mind also having the ability to manipulate block properties using clicking (mainly visibility)
Clicking is no problem ... making the cursor know what is below it is a whole other ball-game. It would probably involve ray-tracing. That's a processor-intensive task. You should save that thought for later and see if there is processor-time for it. 
I'll suggest that you use the numeric tastatur/keyboard to tab through the blocks (4&6 for left7right, 8&2 for up/down, 1&9 for in/out). But you'll probably have to start thinking of a sort of interface for the user. You often see two buttons that controls the state of how the cursor is used (one for 'state position' that puts mouse-input into a camera-translate .. and one for 'state-direction' where input goes into camera-rotate). You can start out assigning key-strokes for the 'states' and save the gui-work till later.  From own experience: I've used the numeric keys for a controlled 15 deg step rotation of the camera (around the model). And, a 'reset-camera parameters' key for when you get lost in space ;o)
After picking a particular shape/group .. a currentBlock/group object may be handy and redirect the drawing to just do that or turn the rest into a wire-frame presentation (that function may not be available).


... as for the problem in my previous post: Found this in the pVector library:
angleBetween() Calculates the angle between two vectors
[EDIT]

I commented out the peasy stuff and had a look at the temple
My suggestion of doing a 'block' and copy it is not applicable. And it's not necessary. 
About flipping axis .. it could be a question of feeding the right parameters to the camera.

Is it a coincident that you've chosen to draw the blocks in proper order (bottom ones first) .. or does processing take care of the z-buffering (the task in camera-space to reorder the shapes to be drawn with the most distant ones first) ?

--------
I think that you should load 1 model with all its blocks (at time=0). 
The next step is to pick one vector (from two vertices in x-z plane) from each block + the direction-vector (assumed to be the original up-vector). 
Then, for each iteration of the software-earthquake, you read the same block-vector and direction (without downloading all info).
In each increment the vector-difference (to the previous) may be very small, so it could be worth while to compare it to the vector a time=0. You don't know what direction in the x-z plane it represents (temperary x), but that doesn't matter becourse you only needs the difference.
By normalizing the vector (divide each component with the vector-length) and vector-cross-producting with the direction-vector (assumed to be normalized) you get the last primary axis. Many ways leads to Rome .. which one you choose doesn't matter .. in particular becourse there is no constraint on how many resources you put into it (it's a pre-processing step that should take place before you start drawing anything)
Finally ... the rotation-matrix may be more difficult to construct than I imply. It's probably composed of sums of products of coss and sins. I promise to look into it.
                        -------- ( looking  )----------
This is a good source for rotation scrutiny
I use the chapter 'Rotation Matrix Conventions' as a suggestion to put the 3 unite vectors above right into a matrix (M1). This matrix transforms (1,0,0),(0,1,0),(0,0,1) into the vectors. (it appear conspicuously easy .. did I forget something?). 
We did not start out with a reference represented by  (1,0,0),(0,1,0),(0,0,1), but one that had already been imposed an angular rotation around up (0,1,0). Ill call it (x1,0,z1),(0,1,0),(x2,0,x2) [= the normalized 'temp x & z'] . If I'm not mistaken, an inverse rotation-matrix is created by transposing the forward matrix. 
If we do the trick again .. using the 3 unite vectors (x1,0,z1),(0,1,0),(x2,0,x2)  to fill a matrix and transpose it (M2), where are we then?
If v is the arbitrary vector we picked in the x-z plane 'as temporary x' then
v*M2 -> takes you an angle round (0,1,0) to place it in parallel with (1,0,0). *M1 -> takes it from here to it's destination. Here you can translate it with the position-vector and it ought to be HOME, .. right?
M2 and M1 can be matrix-multiplied (watch out for proper order), but keep the position translation to itself and apply it last.