Пример #1
0
void grPropagateDamage (ssgEntity* l, sgVec3 poc, sgVec3 force, int cnt)
{
	//showEntityType (l);
	if (l->isAKindOf (ssgTypeBranch())) {
		
		ssgBranch* br = (ssgBranch*) l;

		for (int i = 0 ; i < br -> getNumKids () ; i++ ) {
			ssgEntity* ln = br->getKid (i);
			grPropagateDamage(ln, poc, force, cnt+1);
		}
	}
	
	if (l->isAKindOf (ssgTypeVtxTable())) {
		sgVec3* v;
		int Nv;
		ssgVtxTable* vt = (ssgVtxTable*) l;
		Nv = vt->getNumVertices();
		vt->getVertexList ((void**) &v);
		tdble sigma = sgLengthVec3 (force);
		tdble invSigma = 5.0;

		for (int i=0; i<Nv; i++) {
			tdble r =  sgDistanceSquaredVec3 (poc, v[i]);
			tdble f = exp(-r*invSigma)*5.0;
			v[i][0] += force[0]*f;
			v[i][1] += force[1]*f;
			// use sigma as a random number generator (!)
			v[i][2] += (force[2]+0.02*sin(2.0*r + 10.0*sigma))*f;
			//printf ("(%f %f %f)\n", v[i][0], v[i][1], v[i][2]);
		}
	}
}
Пример #2
0
void StaticWorldObject::WalkTree(ssgEntity *e, sgVec3 initialpos)
{
  if (!e) return;
  if (e->isAKindOf (ssgTypeBranch()) )
  {
    ssgBranch *branch = (ssgBranch*) e ;
    for (int i=0; i<branch->getNumKids(); i++)
    {
      ssgEntity *kid = branch->getKid(i);
      assert(kid!=NULL);
      WalkTree(kid, initialpos);
    }
  }
  if ( e->isAKindOf ( ssgTypeLeaf () ) )
  {
    AddLeaf((ssgLeaf*)e, initialpos);
  }
}
Пример #3
0
/**
 *  \brief Locate a named SSG node in a branch.
 *
 *  This method locates a named node in an SSG scenegraph branch. The
 *  node name usually corresponds to the name of an object in the 3D model.
 *
 *  This method was taken from SimGear, credits go to the original
 *  authors.
 *
 *  \param  node    Pointer to the scenegraph branch
 *  \param  name    Name of the object to search for
 *  \return Pointer to the node or NULL if no node with this name was found
 */
ssgEntity* SSGUtil::findNamedNode (ssgEntity* node, const char* name)
{
  std::string NodeName = SSGUtil::getPureNodeName(node);
  if (NodeName == name)
  {
    return node;
  }
  else if (node->isAKindOf(ssgTypeBranch()))
  {
    int nKids = node->getNumKids();
    for (int i = 0; i < nKids; i++)
    {
      ssgEntity * result =
        findNamedNode(((ssgBranch*)node)->getKid(i), name);
      if (result != 0)
      {
        return result;
      }
    }
  } 
  return NULL;
}
Пример #4
0
/**
 * Recursively walk a scene graph and evaluate any node
 * attributes placed inside the name strings of leaves.
 *
 */
void ModelBasedScenery::evaluateNodeAttributes(ssgEntity* ent)
{
  if (ent->isAKindOf(ssgTypeLeaf()))
  {
    SSGUtil::NodeAttributes attr = SSGUtil::getNodeAttributes(ent);
    std::string node_name = SSGUtil::getPureNodeName(ent);
    
    if (attr.checkAttribute("terrain") == -1)
    {
      ent->clrTraversalMaskBits(SSGTRAV_HOT | SSGTRAV_LOS);
      std::cout << "  leaf \"" << node_name 
                << "\" is excluded from terrain calculations (found -terrain attribute)"
                << std::endl;
    }
    if (attr.checkAttribute("visible") == -1)
    {
      std::cout << "  leaf \"" << node_name 
                << "\" is invisible (found -visible attribute)"
                << std::endl;
      SSGUtil::spliceBranch(new ssgInvisible(), ent);
    }
    
  }
  else if (ent->isAKindOf(ssgTypeBranch()))
  {
    ssgBranch *branch = (ssgBranch*)ent;

    // continue down the hierarchy
    int kids = branch->getNumKids();
    for (int i = 0; i < kids; i++)
    {
      ssgEntity* currKid = branch->getKid(i);
      evaluateNodeAttributes(currKid);
    }
  }
}
Пример #5
0
void ModelBasedScenery::setToInvisibleState(ssgEntity* ent)
{
  if (ent->isAKindOf(ssgTypeLeaf()))
  {
    ssgLeaf *leaf = (ssgLeaf*)ent;

    if (leaf->hasState())
    {
      leaf->setState(invisible_state);
    }
  }
  else if (ent->isAKindOf(ssgTypeBranch()))
  {
    ssgBranch *branch = (ssgBranch*)ent;

    // continue down the hierarchy
    int kids = branch->getNumKids();
    for (int i = 0; i < kids; i++)
    {
      ssgEntity* currKid = branch->getKid(i);
      setToInvisibleState(currKid);
    }
  }
}
Пример #6
0
/**
 * \brief Tile the terrain
 *
 * This function recursively walks the scene graph and sorts all
 * triangles into a grid of smaller graphs. This reduces the
 * calculation effort: If the position of the plane and therefore
 * the grid below it is known, only a small fraction of all
 * triangles has to be tested.
 *
 * During the recursive walk down the tree, the function tracks
 * all transformations. If a leaf node is encountered, the contained
 * triangles are transformed by the tracked transformations to
 * get the absolute position of each triangle. Then all triangles
 * are sorted into the grid by their absolute position.
 *
 * \param e       Pointer to the currently processed entity
 * \param xform   Reference to the current transformation
 */
void HD_TilingTerrain::tiling_terrain(ssgEntity * e, sgMat4 xform)
{
  // only continue if HOT traversal is enabled for this entity
  if ( e->getTraversalMask() & SSGTRAV_HOT )
  {
    if ( e->isAKindOf(ssgTypeBranch()) )
    {
      ssgBranch *br = (ssgBranch *) e ;
      if ( e -> isA ( ssgTypeTransform() ) )
      {
        sgMat4 xform1;
        ((ssgTransform *)e)->getTransform ( xform1 ) ;
        sgPreMultMat4  ( xform, xform1 ) ;//Pre or Post ???
        /*
        std::cout << "------tranform " << br<< std::endl;
        std::cout << "-------------- " << xform[0][0]<<"  "<< xform[0][1]<<"  "<< xform[0][2]<<"  "<< xform[0][3]<< std::endl;
        std::cout << "-------------- " << xform[1][0]<<"  "<< xform[1][1]<<"  "<< xform[1][2]<<"  "<< xform[1][3]<< std::endl;
        std::cout << "-------------- " << xform[2][0]<<"  "<< xform[2][1]<<"  "<< xform[2][2]<<"  "<< xform[2][3]<< std::endl;
        std::cout << "-------------- " << xform[3][0]<<"  "<< xform[3][1]<<"  "<< xform[3][2]<<"  "<< xform[3][3]<< std::endl;
        */
      }
      //else std::cout << "------branch " << br<< std::endl;
      
      // Bug #16552: "xform" is actually passed by reference and
      // not by value. Therefore we have to store it locally and
      // restore it before recursing to the next child. Else all
      // children receive an xform matrix that was modified by
      // the previous child.
      sgMat4 local_xform;
      sgCopyMat4(local_xform, xform);
      for ( int i = 0 ; i < br -> getNumKids () ; i++ )
      {
        tiling_terrain ( br -> getKid ( i ), xform);
        // restore transformation matrix
        sgCopyMat4(xform, local_xform);
      }
    }
    else if ( e -> isAKindOf ( ssgTypeLeaf() ) )
    {
      //std::cout << "------leaf " << e<< std::endl;
      ssgLeaf  *leaf = (ssgLeaf  *) e ;
      int nt = leaf->getNumTriangles();
      //std::cout << "------n triangles " << nt<< std::endl;
      for ( int i = 0 ; i < nt ; i++ )//pour chaque triangle
      {
        short iv1,iv2,iv3;/*float *v1, *v2, *v3;*/
        sgVec3 v1,v2,v3;
        leaf->getTriangle ( i, &iv1, &iv2,  &iv3 );

        sgCopyVec3 (v1 , leaf->getVertex(iv1));
        sgXformPnt3( v1, xform);
        sgCopyVec3 (v2 , leaf->getVertex(iv2));
        sgXformPnt3( v2, xform);
        sgCopyVec3 (v3 , leaf->getVertex(iv3));
        sgXformPnt3( v3, xform);
        /*
        std::cout << "------triangle " << std::endl;
        std::cout << "-------------- " << v1[0]<<"  "<< v1[1]<<"  "<< v1[2]<<"  "<< std::endl;
        std::cout << "-------------- " << v2[0]<<"  "<< v2[1]<<"  "<< v2[2]<<"  "<< std::endl;
        std::cout << "-------------- " << v3[0]<<"  "<< v3[1]<<"  "<< v3[2]<<"  "<< std::endl;
        */
        //calcule cube englobant
        sgBox box;
        box.empty();
        box.extend(v1);
        box.extend(v2);
        box.extend(v3);
        //std::cout << "Min " << box.min[0]<<", "<<box.min[1]<<", "<<box.min[2]<<" Max"<<box.max[0]<<", "<<box.max[1]<<", "<<box.max[2]<< std::endl;
        //ajoute dans cellules recouvertes
        int save =  1;
        int i1 = (int)(-0.1+box.min[0]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2;
        int i2 = (int)(0.1+box.max[0]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2;
        int j1 = (int)(-0.1+box.min[2]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2;
        int j2 = (int)(0.1+box.max[2]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2;
        if (((i1<0) && (i2<0)) ||((i1>SIZE_GRID_PLANES) && (i2>SIZE_GRID_PLANES)) )
        {
          save = 0;
        }
        if (((j1<0) && (j2<0)) ||((j1>SIZE_GRID_PLANES) && (j2>SIZE_GRID_PLANES)) )
        {
          save = 0;
        }
        if (i1<0)
          i1=0;
        if (i1>SIZE_GRID_PLANES)
          i1 = SIZE_GRID_PLANES;
        if (i2<0)
          i2=0;
        if (i2>SIZE_GRID_PLANES)
          i2 = SIZE_GRID_PLANES;
        if (j1<0)
          j1=0;
        if (j1>SIZE_GRID_PLANES)
          j1 = SIZE_GRID_PLANES;
        if (j2<0)
          j2=0;
        if (j2>SIZE_GRID_PLANES)
          j2 = SIZE_GRID_PLANES;
        //std::cout << "cellules i, j  " << i1 <<", "<<i2<<", "<<j1<<","<<j2<< std::endl;
        if (save)
        {
          for ( int i = i1 ; i <= i2; i++ )
          {
            for ( int j = j1 ; j <= j2; j++ )
            {
              //std::cout << "met dans cellule " << i <<", "<<j<<  std::endl;
              tile_table[i][j]->add(v1);
              tile_table[i][j]->add(v2);
              tile_table[i][j]->add(v3);
            }
          }
        }
      }
    }
  }
}
Пример #7
0
/** \brief Create a "shadow" instance of a model
 *
 *  This function operates on a clone of a model and sets all associated
 *  states to a "shadowy" look. If it is called for an entity that has the
 *  "-shadow" attribute set, return true to signal the caller that he has to
 *  remove this entity from the graph.
 *  
 *  \todo If the video context supports stencil buffering, the shadow
 *        should be rendered using the stencil buffer to get a translucent look.
 *
 *  \param ent  A clone of the "real" model
 *  \retval true The current entity has to be removed from the graph
 *  \retval false No action required
 */
bool makeShadow(ssgEntity *ent)
{
  bool boRemoveCurrentEntity = false;
  
  if (ent->isAKindOf(ssgTypeLeaf()))
  {
    ssgLeaf *leaf = (ssgLeaf*)ent;

    SSGUtil::NodeAttributes attr = SSGUtil::getNodeAttributes(leaf);
    if (!attr.castsShadow)
    {
      // no shadow --> remove this entity from all parents
      boRemoveCurrentEntity = true;
    }
    else if (leaf->hasState())
    {
      ssgSimpleState *state = (ssgSimpleState*)leaf->getState();
      state->disable(GL_COLOR_MATERIAL);
      state->disable(GL_TEXTURE_2D);
      state->enable(GL_LIGHTING);
      state->enable(GL_BLEND);
      state->setShadeModel(GL_SMOOTH);
      state->setShininess(0.0f);
      state->setMaterial(GL_EMISSION, 0.0, 0.0, 0.0, 0.0);
      
      #ifdef EXPERIMENTAL_STENCIL_SHADOW
      if (vidbits.stencil)
      {
        state->setMaterial(GL_AMBIENT, 0.0, 0.0, 0.0, 0.1);
        state->setMaterial(GL_DIFFUSE, 0.0, 0.0, 0.0, 0.1);
        state->setMaterial(GL_SPECULAR, 0.0, 0.0, 0.0, 0.1);
        state->setStateCallback(SSG_CALLBACK_PREDRAW, shadowPredrawCallback);
        state->setStateCallback(SSG_CALLBACK_POSTDRAW, shadowPostdrawCallback);
      }
      else
      #endif
      {
        state->setMaterial(GL_AMBIENT, 0.0, 0.0, 0.0, 1.0);
        state->setMaterial(GL_DIFFUSE, 0.0, 0.0, 0.0, 1.0);
        state->setMaterial(GL_SPECULAR, 0.0, 0.0, 0.0, 1.0);
        state->setStateCallback(SSG_CALLBACK_PREDRAW, NULL);
        state->setStateCallback(SSG_CALLBACK_POSTDRAW, NULL);
      }
    }
  }
  else if (ent->isAKindOf(ssgTypeBranch()))
  {
    ssgBranch *branch = (ssgBranch*)ent;

    // continue down the hierarchy
    std::list<ssgLeaf*> ToBeRemoved;
    std::list<ssgLeaf*>::iterator it;
    int kids = branch->getNumKids();
    for (int i = 0; i < kids; i++)
    {
      ssgEntity* currKid = branch->getKid(i);
      if (makeShadow(currKid))
      {
        ToBeRemoved.push_back(static_cast<ssgLeaf*>(currKid));
      }
    }
    for (it = ToBeRemoved.begin(); it != ToBeRemoved.end(); it++)
    {
      SSGUtil::removeLeafFromGraph(*it);
    }
    

  }
  return boRemoveCurrentEntity;
}