Esempio n. 1
0
void
SoFile::copyContents(const SoFieldContainer *fromFC, SbBool copyConnections)
//
////////////////////////////////////////////////////////////////////////
{
    // Detach sensor temporarily so we do not read the file again
    nameChangedSensor->detach();

    // Copy the usual stuff
    SoNode::copyContents(fromFC, copyConnections);

    // Copy the kids
    const SoFile *fromGroup = (const SoFile *) fromFC;
    SoChildList *fromChildren = fromGroup->getChildren();
    for (int i = 0; i < fromChildren->getLength(); i++) {

	// If this node is being copied, it must be "inside" (see
	// SoNode::copy() for details.) Therefore, all of its children
	// must be inside, as well.
	SoNode *fromKid = (*fromChildren)[i];
	SoNode *kidCopy = (SoNode *) findCopy(fromKid, copyConnections);

#ifdef DEBUG
	if (kidCopy == NULL)
	    SoDebugError::post("(internal) SoFile::copyContents",
			       "Child %d has not been copied yet", i);
#endif /* DEBUG */

	children.append(kidCopy);
    }
    
    // Reattach sensor
    nameChangedSensor->attach(&name);
}
/*! \fn SoXipGLSLUniformGroup::doAction(SoAction * action)
 *  Adds a node to the SoXipGLSLUniformGroupElement in the current state
 *  \param action - the current state action, no action taken if input action is NULL
 *  \return void
 */
void SoXipGLSLUniformGroup::groupUpdate(SoAction * action)
{
    SoChildList * children = this->getChildren();
    GLint prg = SoXipGLSLShaderProgramElement::get(action->getState());

    if (mNumPrograms > GLSL_MAX_NUM_SHADERS)
    {
        SoDebugError::postWarning(__FUNCTION__, "supports %i shaders (requested %d)", GLSL_MAX_NUM_SHADERS, mNumPrograms);
        mNumPrograms = GLSL_MAX_NUM_SHADERS;
    }

    for (int i = 0; i < mNumPrograms; i++)
    {
/*
    To prevent uniforms from updating every frame
    we only update the uniform if the time stamp
    of the selected shader is out of date or if
    anything has changed among the uniforms such
    as names or values.

    TODO: This fix do not work since we have no
    way of knowing if other instances of this
    node also changes the same uniforms. Since
    this will not change the timestamp in the
    manager the uniform remains as last updated
    and fix don't work.

    No solution to the problem yet!
    Stefan Lindholm
*/
#if 0
        int handle = SoXipGLSLShaderProgramElement::getProgramID(action->getState(), prgTags[i].getString());
        if (glIsProgram(handle))
        {
            SoXipGLSLShaderProgramElement::set(action->getState(), prgTags[i].getString());
            children->traverse(action);
        }
#else
        __uint64 currTime = SoXipGLSLShaderProgramElement::getTimeStamp(action->getState(), prgTags[i].getString());
        if (currTime != mProgramTimeStamps[i] || mNeedsUpdate)
        {
            SoXipGLSLShaderProgramElement::set(action->getState(), prgTags[i].getString());
            children->traverse(action);
            mProgramTimeStamps[i] = currTime;
        }
#endif
    }

    SoXipGLSLShaderProgramElement::set(action->getState(), prg);
    mNeedsUpdate = false;
}
Esempio n. 3
0
/*!
  Updates \a path to be the same path as this path.
*/
void
SoLightPath::makeTempPath(SoTempPath *path) const
{
  const int n = this->indices.getLength();
  SoNode *node = this->headnode;
  path->setHead(node);
  for (int i = 1; i < n; i++) {
    int childidx = this->indices[i];
    // check validity of path, return if invalid
    SoChildList *children = node->getChildren();
    if (children == NULL || childidx < 0 || childidx >= children->getLength()) break;
    node = (*children)[childidx];
    path->append(childidx); // childidx should be ok
  }
}
Esempio n. 4
0
/*!
  Add a copy of this node and (recursively) all children to the copy
  dictionary of SoFieldContainer if this has not already been done.

  Used internally during copy operations.
*/
SoNode *
SoNode::addToCopyDict(void) const
{
#if COIN_DEBUG && 0 // debug
  SoDebugError::postInfo("SoNode::addToCopyDict",
                         "%s node", this->getTypeId().getName().getString());
#endif // debug

  SoNode * cp = (SoNode *)SoFieldContainer::checkCopy(this);
  if (!cp) {
    // We need to do some extra work when copying nodes that are
    // ProtoInstance root nodes. We create a new ProtoInstance node,
    // and register its root node as the copy. pederb, 2002-06-17
    SoProtoInstance * inst = SoProtoInstance::findProtoInstance(this);
    if (inst) {
      SoProto * proto = inst->getProtoDefinition();
      SoProtoInstance * newinst = proto->createProtoInstance();
      if (inst->getName().getLength()) newinst->setName(inst->getName());
      cp = newinst->getRootNode();
      assert(cp);
      // We have to call addCopy() before calling copyContents() since
      // the proto instance might have a field that has a pointer to
      // the root node. pederb, 2002-09-04
      SoFieldContainer::addCopy(this, cp);
      newinst->copyContents(inst, FALSE);
    }
    else {
      if (this->isOfType(SoProto::getClassTypeId())) {
        // just copy the pointer. A PROTO definition is
        // read-only. It's not possible to change it after it has been
        // created so this should be safe.
        cp = (SoNode*) this;
      }
      else {
        cp = (SoNode *)this->getTypeId().createInstance();
      }
      assert(cp);
      SoFieldContainer::addCopy(this, cp);

      SoChildList * l = this->getChildren();
      for (int i=0; l && (i < l->getLength()); i++)
        (void)(*l)[i]->addToCopyDict();
    }
  }
  return cp;
}
Esempio n. 5
0
/*!
  Returns the indexth node in path.
*/
SoNode *
SoLightPath::getNode(const int index) const
{
#if COIN_DEBUG && 1 // debug
  if (index < 0 || index >= this->indices.getLength()) {
    SoDebugError::postInfo("SoLightPath::getNode",
                           "index %d out of bounds", index);
  }
#endif // debug

  SoNode *node = this->headnode;
  for (int i = 1; i < index; i++) {
    int childidx = this->indices[i];
    SoChildList *children = node->getChildren();
    node = NULL;
    if (children == NULL || childidx < 0 || childidx >= children->getLength()) break;
    node = (*children)[childidx];
  }
  return node;
}
Esempio n. 6
0
static SoSeparator *
setUpGraph(const SbViewportRegion &vpReg,
	   SoInput *sceneInput,
	   Options &options)
//
//////////////////////////////////////////////////////////////
{

    // Create a root separator to hold everything. Turn
    // caching off, since the transformation will blow
    // it anyway.
    SoSeparator *root = new SoSeparator;
    root->ref();
    root->renderCaching = SoSeparator::OFF;

    // Add a camera to view the scene
    SoPerspectiveCamera *camera = new SoPerspectiveCamera;
    root->addChild(camera);

    // Add a transform node to spin the scene
    SoTransform *sceneTransform = new SoTransform;
    sceneTransform->setName(SCENE_XFORM_NAME);
    root->addChild(sceneTransform);

    // Read and add input scene graph
    SoSeparator *inputRoot = SoDB::readAll(sceneInput);
    if (inputRoot == NULL) {
	fprintf(stderr, "Cannot read scene graph\n");
	root->unref();
	exit(1);
    }
    root->addChild(inputRoot);

    SoPath 	*path;
    SoGroup	*parent, *group;
    SoSearchAction	act;

    // expand out all File nodes and replace them with groups
    //    containing the children
    SoFile 	*fileNode;
    act.setType(SoFile::getClassTypeId());
    act.setInterest(SoSearchAction::FIRST);
    act.apply(inputRoot);
    while ((path = act.getPath()) != NULL) {
	fileNode = (SoFile *) path->getTail();
	path->pop();
	parent = (SoGroup *) path->getTail();
	group = fileNode->copyChildren();
	if (group) {
	    parent->replaceChild(fileNode, group);
	    // apply action again and continue
	    act.apply(inputRoot);
	}
    }

    // expand out all node kits and replace them with groups
    //    containing the children
    SoBaseKit	*kitNode;
    SoChildList	*childList;
    act.setType(SoBaseKit::getClassTypeId());
    act.setInterest(SoSearchAction::FIRST);
    act.apply(inputRoot);
    while ((path = act.getPath()) != NULL) {
	kitNode = (SoBaseKit *) path->getTail();
	path->pop();
	parent = (SoGroup *) path->getTail();
	group = new SoGroup;
	childList = kitNode->getChildren();
	for (int i=0; i<childList->getLength(); i++) 
	    group->addChild((*childList)[i]);
	parent->replaceChild(kitNode, group);
	act.apply(inputRoot);
    }

    // check to see if there are any lights
    // if no lights, add a directional light to the scene
    act.setType(SoLight::getClassTypeId());
    act.setInterest(SoSearchAction::FIRST);
    act.apply(inputRoot);
    if (act.getPath() == NULL) { // no lights
	SoDirectionalLight *light = new SoDirectionalLight;
	root->insertChild(light, 1);
    }
    else 
	options.hasLights = TRUE;

    // check to see if there are any texures in the scene
    act.setType(SoTexture2::getClassTypeId());
    act.setInterest(SoSearchAction::FIRST);
    act.apply(inputRoot);
    if (act.getPath() != NULL)
	options.hasTextures = TRUE;

    camera->viewAll(root, vpReg);

    // print out information about the scene graph

    int32_t numTris, numLines, numPoints, numNodes;
    countPrimitives( inputRoot, numTris, numLines, numPoints, numNodes );
    printf("Number of nodes in scene graph:     %d\n", numNodes );
    printf("Number of triangles in scene graph: %d\n", numTris );
    printf("Number of lines in scene graph:     %d\n", numLines );
    printf("Number of points in scene graph:    %d\n\n", numPoints );

    // Make the center of rotation the center of
    // the scene
    SoGetBoundingBoxAction	bba(vpReg);
    bba.apply(root);
    sceneTransform->center = bba.getBoundingBox().getCenter();

    return root;
}
/*! \fn SoXipGLSLUniformGroup::doAction(SoAction * action)
 *  Adds a node to the SoXipGLSLUniformGroupElement in the current state
 *  \param action - the current state action, no action taken if input action is NULL
 *  \return void
 */
void SoXipGLSLUniformGroup::doAction(SoAction * action)
{
    SoChildList * children = this->getChildren();
    children->traverse(action);
}