DMM API Tutorial #1: Creating a simple scene

DMM API code samples and more

DMM API Tutorial #1: Creating a simple scene

Postby dmmNOW on Fri Sep 19, 2008 2:21 am

Creating a simple scene

DMM_API_Tutorial#1.mov
DMM API Tutorial #1: Creating a simple scene
(276.03 KiB) Downloaded 367 times


Code: Select all

#include <DMM.h>
#include <Scene.h>
#include <Object.h>
#include <Node.h>
#include <Material.h>

// This is a primitive cube as created by the DMM Plugin
// It has 12 tets, each of them using a triangle of the cube
// shape as its base and the center of the cube as its top

// List of nodes (vertices)
const size_t numNodes = 9;
Pixelux::real cubeNodes[numNodes][3] = {
   { -0.5, -0.5, 0.5 },    // Corner #0
   { 0.5, -0.5, 0.5 },     // ...
   { 0.5, 0.5, 0.5 },      // ...
   { -0.5, 0.5, 0.5 },     // ...
   { 0.5, 0.5, -0.5 },     // ...
   { -0.5, 0.5, -0.5 },    // ...
   { 0.5, -0.5, -0.5 },    // ...
   { -0.5, -0.5, -0.5 },   // Corner #7
   { 0.0, 0.0, 0.0 } };    // Center

// List of indices making the tets
const size_t numTets = 12;
size_t cubeTets[numTets][4] = {
   { 1, 0, 8, 3 },         // Tet #0
   { 7, 0, 8, 1 },         // ...
   { 5, 0, 3, 8 },         // ...
   { 5, 0, 8, 7 },         // ...
   { 2, 1, 8, 3 },         // ...
   { 6, 1, 8, 2 },         // ...
   { 1, 8, 7, 6 },         // ...
   { 2, 3, 8, 5 },         // ...
   { 2, 4, 5, 8 },         // ...
   { 4, 8, 2, 6 },         // ...
   { 4, 8, 6, 5 },         // ...
   { 6, 5, 8, 7 } };       // Tet #11

// List of tet nodes making the tet's triangles
size_t tetFaceNode[4][3] = {
   { 0, 1, 2 },            // Triangle #0
   { 2, 3, 0 },            // ...
   { 2, 1, 3 },            // ...
   { 3, 1, 0 } };          // Triangle #3

// Storage space for the simulated node's positions
Pixelux::Vec3 nodePositions[4 * numTets];

// The DMM singleton
Pixelux::DMM* pDMM = NULL;

// The DMM scene
Pixelux::Scene* pDMMScene = NULL;

// Initialize DMM and create the Scene
bool InitDMM()
{
   bool success = false;

   // Get DMM
   pDMM = Pixelux::GetDMM(PXX_DMM_VERSION);
   if (pDMM == NULL)
   {
      // Couldn't get DMM - probably wrong version number
   }
   else
   {
      // Create the scene
      pDMMScene = pDMM->CreateScene();
      success = true;
   }

   return success;
}

// Deletes the DMM scene
void DeleteDMMScene()
{
   if ((pDMM != NULL) && (pDMMScene != NULL))
   {
      pDMM->DeleteScene(pDMMScene);
      pDMMScene = NULL;
   }
}

// Add a DMM cube primitive to the scene, with a scale and a translation
Pixelux::Object* CreateDMMCube(const Pixelux::Vec3& scale, const Pixelux::Vec3& trans)
{
   // Create the object
   Pixelux::Object* pObject = pDMMScene->CreateObject(4 * numTets, numTets);
   if (pObject != NULL)
   {
      // Create the nodes (vertices)
      for (size_t i = 0; i < numNodes; ++i)
      {
         // Initialize a Vec3 with the node position
         Pixelux::Vec3 v;
         v.x = cubeNodes[i][0];
         v.y = cubeNodes[i][1];
         v.z = cubeNodes[i][2];

         // Scale and translate
         v.mult(scale);
         v.add(trans);

         // Create node
         pObject->CreateNode(v);
      }

      // Create the tets
      Pixelux::Node** beginNodes = pObject->BeginNodes();
      for (size_t i = 0; i < numTets; ++i)
      {
         // Get the 4 nodes forming the tet
         size_t n0 = cubeTets[i][0];
         size_t n1 = cubeTets[i][1];
         size_t n2 = cubeTets[i][2];
         size_t n3 = cubeTets[i][3];
         Pixelux::Node* nodes[] = {
            beginNodes[n0], beginNodes[n1], beginNodes[n2], beginNodes[n3] };

         // Create the tet
         pObject->CreateTet(nodes);
      }
   }

   return pObject;
}

bool CreateDMMObjects()
{
   if (pDMMScene == NULL)
   {
      return false;
   }

   // Create a new material
   Pixelux::Material* pMaterial = pDMMScene->CreateMaterial();

   if (pMaterial == NULL)
   {
      return false;
   }

   // Make it quite heavy and mushy
   pMaterial->SetName("myMaterial");
   pMaterial->Set(Pixelux::MATERIAL_DENSITY, 1e4);
   pMaterial->Set(Pixelux::MATERIAL_YOUNGS_MODULUS, 1e6);

   // Set it as the default material
   // (every newly created tet will use that material)
   pDMMScene->SetDefaultMaterial(pMaterial);

   // Create a cube that's translated it upwards,
   Pixelux::Vec3 scale(1);
   Pixelux::Vec3 trans(0);
   trans.y = 4;
   Pixelux::Object* pObject = CreateDMMCube(scale, trans);

   if (pObject == NULL)
   {
      return false;
   }

   // Create another cube, flattened and translated downward
   scale.x *= 10;
   scale.y *= 0.2;
   scale.z *= 10;
   trans.y = -2;
   pObject = CreateDMMCube(scale, trans);

   if (pObject == NULL)
   {
      return false;
   }

   // Let the first cube fall down on the second cube
   // => drive the node's positions of the second cube so it won't move
   //    (it would be a passive object in the DMM Plugin)
   // To do that, iterate each node of the second cube
   for (Pixelux::Node** it = pObject->BeginNodes(), ** end = pObject->EndNodes()
      ; it != end; ++it)
   {
      // And set the node as "driven"
      Pixelux::Node* pNode = *it;
      pNode->SetNodeState(Pixelux::NODE_DRIVEN_BIT);
   }

   return true;
}

void StepDMMSim()
{
   if (pDMMScene != NULL)
   {
      // Mode 10 ms forward in the DMM simulation
      pDMMScene->Step(0.01);

      // Wait for 5 ms before returning
      // This is very innacurate, it's just to emulate
      // other computations that would be done in a game engine
      Sleep(5);
   }
}

void DrawDMMObjects()
{
   // Reset the model-view matrix
   glLoadIdentity();

   // And translate and rotate the objects so to better see them
   glTranslatef(0.0f,0.0f,-7.0f);
   glRotatef(30,0.0f,1.0f,0.0f);

   // Iterate the DMM objects
   for (Pixelux::Object** it = pDMMScene->BeginObjects(), ** end = pDMMScene->EndObjects()
      ; it != end; ++it)
   {
      // Get the node positions for this DMM object
      Pixelux::Object* pObject = *it;
      pObject->GetTetsNodesPos(pObject->BeginTets(), pObject->EndTets(), &nodePositions[0]);

      // Start drawing triangles
      glBegin(GL_TRIANGLES);

      // Iterate the tets
      for (size_t i = 0; i < numTets; ++i)
      {
         // Iterate the tet's triangles
         for (size_t j = 0; j < 4; ++j)
         {
            // Get the node's positions for this triangle
            Pixelux::Vec3& v0 = nodePositions[4 * i + tetFaceNode[j][0]];
            Pixelux::Vec3& v1 = nodePositions[4 * i + tetFaceNode[j][1]];
            Pixelux::Vec3& v2 = nodePositions[4 * i + tetFaceNode[j][2]];

            // Draw one face (triangle) of the tet

            // 1st vertex, green
            glColor3f(0, 1, 0);
            glVertex3f(v0.x, v0.y, v0.z);

            // 2nd vertex, red
            glColor3f(1, 0, 0);
            glVertex3f(v1.x, v1.y, v1.z);

            // 3rd vertex, blue
            glColor3f(0, 0, 1);
            glVertex3f(v2.x, v2.y, v2.z);
         }
      }

      // Done with drawing the tets
      glEnd();
   }
}
Trying to DMMize my C++ compiler
User avatar
dmmNOW
 
Posts: 12
Joined: Fri Sep 19, 2008 2:18 am

Re: DMM API Tutorial #1: Creating a simple scene

Postby Friktion on Tue Mar 09, 2010 5:48 am

Great seems simple enough.
And the only way of getting this api is to send that message ?
Friktion
 
Posts: 1
Joined: Mon Mar 08, 2010 2:04 pm

Re: DMM API Tutorial #1: Creating a simple scene

Postby dmmNOW on Tue Mar 16, 2010 9:22 am

We will soon release a free version of the API, see this thread.
Trying to DMMize my C++ compiler
User avatar
dmmNOW
 
Posts: 12
Joined: Fri Sep 19, 2008 2:18 am


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest