Logo Search packages:      
Sourcecode: whitedune version File versions  Download package

NodeNurbsPositionInterpolator.cpp

/*
 * NodeNurbsPositionInterpolator.cpp
 *
 * Copyright (C) 1999 Stephen F. White, 2004 J. "MUFTI" Scheurich
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include "stdafx.h"

#include "NodeNurbsPositionInterpolator.h"
#include "Proto.h"
#include "DuneApp.h"
#include "Scene.h"
#include "FieldValue.h"
#include "SFFloat.h"
#include "SFInt32.h"
#include "SFBool.h"
#include "Vec2f.h"

ProtoNurbsPositionInterpolator::ProtoNurbsPositionInterpolator(Scene *scene)
  : Proto(scene, "NurbsPositionInterpolator")
{
    dimension.set(
          addExposedField(SFINT32, "dimension", new SFInt32(0)));
    keyValue.set(
          addExposedField(MFVEC3F, "keyValue", new MFVec3f()));
    keyWeight.set(
          addExposedField(MFDOUBLE, "keyWeight", new MFDouble(), new SFFloat(0.0f)));
    knot.set(
          addField(MFDOUBLE, "knot", new MFDouble()));
    order.set(
          addField(SFINT32, "order", new SFInt32(3), new SFInt32(2)));
}

Node *
ProtoNurbsPositionInterpolator::create(Scene *scene)
{
    return new NodeNurbsPositionInterpolator(scene, this); 
}

NodeNurbsPositionInterpolator::NodeNurbsPositionInterpolator(Scene *scene, Proto *def)
  : Node(scene, def)
{
    _nurbsCurveDirty = true;
    _nurbsCurve = (NodeNurbsCurve *) scene->createNode("NurbsCurve");
}

NodeNurbsPositionInterpolator::~NodeNurbsPositionInterpolator()
{
    delete _nurbsCurve;
}

void
NodeNurbsPositionInterpolator::createNurbsCurve()
{
    int i;
    float *points = new float[keyValue()->getSize()];
    for (i = 0; i < keyValue()->getSize(); i++)
         points[i] = keyValue()->getValues()[i];
    _nurbsCurve->controlPoint(new MFVec3f(points, keyValue()->getSize()));
    float *weights = new float[keyWeight()->getSize()];
    for (i = 0; i < keyWeight()->getSize(); i++)
         weights[i] = keyWeight()->getValues()[i];
    _nurbsCurve->weight(new MFFloat(weights, keyWeight()->getSize()));
    float *knots = new float[knot()->getSize()];
    for (i = 0; i < knot()->getSize(); i++)
         knots[i] = knot()->getValues()[i];
    _nurbsCurve->knot(new MFFloat(knots, knot()->getSize()));
    _nurbsCurve->order(new SFInt32(order()->getValue()));
    const Vec3f *chain = _nurbsCurve->getChain();
    int chainLength = _nurbsCurve->getChainLength();
    float *fchain = new float[chainLength * 3];
    for (i = 0; i < chainLength; i++) {
         fchain[i * 3    ] = chain[i].x;
         fchain[i * 3 + 1] = chain[i].y;
         fchain[i * 3 + 2] = chain[i].z;
    }   
    _nurbsCurveDirty = false;
}

bool
NodeNurbsPositionInterpolator::writeEXTERNPROTO(int f)
{
    RET_ONERROR( mywritestr(f ,"EXTERNPROTO NurbsPositionInterpolator[\n") )    
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," eventIn      SFFloat set_fraction\n") ) 
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField SFInt32 dimension\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField MFVec3f keyValue\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField MFFloat keyWeight\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field        MFFloat knot\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field        SFInt32 order\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," eventOut     SFVec3f value_changed\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," ]\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ,"[\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"urn:web3d:vrml97:node:NurbsPositionInterpolator\",\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"urn:inet:blaxxun.com:node:NurbsPositionInterpolator\",\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"urn:ParaGraph:NurbsPositionInterpolator\",\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ,"# \"") )
    RET_ONERROR( mywritestr(f ,"NurbsPositionInterpolatorPROTO.wrl") )
    RET_ONERROR( mywritestr(f ,"\"\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ,"\"") )
    char *dunedocs = getenv("DUNEDOCS");
    if (dunedocs != NULL) {
        RET_ONERROR( mywritestr(f ,dunedocs) )
        RET_ONERROR( mywritestr(f ,"/vrml97Amendment1") )
    }
#ifdef HAVE_SCRIPTED_NODES_PROTO_URL
    else
        RET_ONERROR( mywritestr(f ,HAVE_SCRIPTED_NODES_PROTO_URL) )
#endif
    RET_ONERROR( mywritestr(f ,"/") )
    RET_ONERROR( mywritestr(f ,"NurbsPositionInterpolatorPROTO.wrl") )
    RET_ONERROR( mywritestr(f ,"\"\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"http://www.csv.ica.uni-stuttgart.de/vrml/dune/docs/vrml97Amendment1/NurbsPositionInterpolatorPROTO.wrl\"\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ,"]\n") )
    TheApp->incSelectionLinenumber();
    return true;
}

int             
NodeNurbsPositionInterpolator::write(int filedes, int indent) 
{
    if (_scene->isPureVRML97()) {
/*        
        Node *node = _nurbsCurve->toPositionInterpolator();
        if (node == NULL) 
           return 1;

        // fixme: read Route connects of node and 
        // build routes to new node instead

        RET_ONERROR( node->write(filedes, indent) )
        node->unref();
*/
    } else
        RET_ONERROR( NodeData::write(filedes, indent) )
    return 0;
}

void
NodeNurbsPositionInterpolator::setField(int index, FieldValue *value)
{
    _nurbsCurveDirty = true;
    Node::setField(index, value);
}

void
NodeNurbsPositionInterpolator::draw()
{
    if (_nurbsCurveDirty) {
        createNurbsCurve();
        _nurbsCurveDirty = false;
    }

    if (!_nurbsCurve) return;

    _nurbsCurve->draw();
}

void  
NodeNurbsPositionInterpolator::drawHandles()
{
    if (_nurbsCurveDirty) {
        createNurbsCurve();
        _nurbsCurveDirty = false;
    }

    if (!_nurbsCurve) return;

    _nurbsCurve->drawHandles();
}

Vec3f
NodeNurbsPositionInterpolator::getHandle(int handle, int *constraint,
                      int *field)
{
    *constraint = CONSTRAIN_NONE;
    *field = keyValue_Index() ;

    if (handle >= 0 && handle < keyValue()->getSize() / 3) {
      Vec3f ret((Vec3f)keyValue()->getValue(handle) / 
                   keyWeight()->getValue(handle));
        return ret;
    } else {
        return Vec3f(0.0f, 0.0f, 0.0f);
    }
}


void
NodeNurbsPositionInterpolator::setHandle(int handle, const Vec3f &v) 
{
    MFVec3f    *oldValue = keyValue();
    MFVec3f    *newValue = (MFVec3f *)oldValue->copy();

    if (handle >= 0 && handle < oldValue->getSize() / 3) {
        Vec3f     v2 = v * keyWeight()->getValue(handle);    
        _nurbsCurveDirty = true;
      newValue->setValue(handle * 3, v2.x);
      newValue->setValue(handle * 3+1, v2.y);
      newValue->setValue(handle * 3+2, v2.z);
      _scene->setField(this, keyValue_Index(), newValue);
    }
}

void
NodeNurbsPositionInterpolator::flip(int index)
{
    if (keyValue())
        keyValue()->flip(index);
    _nurbsCurveDirty = true;    
}


Node   *
NodeNurbsPositionInterpolator::toNurbsCurve(void)
{
  NodeNurbsCurve *node = (NodeNurbsCurve *) _scene->createNode("NurbsCurve");
  
  int i;
  float *tmpControlPoints = new float[keyValue()->getSize()];
  float *tmpWeights = new float[keyWeight()->getSize()];
  float *tmpKnots = new float[knot()->getSize()];
  int tmpOrder = order()->getValue();  
  
  for(i=0; i<(keyValue()->getSize()); i++){
    tmpControlPoints[i] = keyValue()->getValues()[i];
  }

  for(i=0; i<(keyWeight()->getSFSize()); i++){
    tmpWeights[i] = keyWeight()->getValue(i);
  }
  
  for(i=0; i<(knot()->getSFSize()); i++){
    tmpKnots[i] = knot()->getValue(i);
  }
    
  node->knot(new MFFloat(tmpKnots, knot()->getSFSize()));
  node->setField(node->order_Index(), new SFInt32(tmpOrder));
  node->controlPoint(new MFVec3f(tmpControlPoints, keyValue()->getSize()));
  node->weight(new MFFloat(tmpWeights, keyWeight()->getSFSize()));

  return node;
}


Generated by  Doxygen 1.6.0   Back to index