/* * 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 #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; }