/* * NodeSphere.cpp * * Copyright (C) 1999 Stephen F. White * 2003 Th. Rothermel * 2004 Wu Qingwei * * 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 "NodeSphere.h" #include "Proto.h" #include "FieldValue.h" #include "Node.h" #include "Scene.h" #include "SFFloat.h" #include "MFNode.h" #include "SFNode.h" #include "SFInt32.h" #include "MFFloat.h" #include "MFVec3f.h" #include "NurbsArc.h" #include "NurbsMakeRevolvedSurface.h" #include "NodeNurbsSurface.h" #include "RenderState.h" #include "Util.h" #include "SFVec3f.h" ProtoSphere::ProtoSphere(Scene *scene) : Proto(scene, "Sphere") { radius.set( addField(SFFLOAT, "radius", new SFFloat(1.0F), new SFFloat(0.0f))); } Node * ProtoSphere::create(Scene *scene) { return new NodeSphere(scene, this); } NodeSphere::NodeSphere(Scene *scene, Proto *def) : Node(scene, def) { } void NodeSphere::draw() { GLUquadricObj *obj = gluNewQuadric(); if (glIsEnabled(GL_TEXTURE_2D)) gluQuadricTexture(obj, GL_TRUE); glPushMatrix(); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); gluSphere(obj, radius()->getValue(), 16, 8); glPopMatrix(); gluDeleteQuadric(obj); } void NodeSphere::drawHandles() { float fradius = radius()->getValue(); RenderState state; glPushMatrix(); glScalef(fradius*1.0f,fradius*1.0f,fradius*1.0f); glPushAttrib(GL_LIGHTING); glDisable(GL_LIGHTING); glPushName(0); Util::myGlColor3f(1.0f, 1.0f, 1.0f); state.startDrawHandles(); for (int i = 0; i < 6; i++) { glLoadName(i); state.drawHandle(spereCorners[i]); } state.endDrawHandles(); glPopName(); glPopAttrib(); glPopMatrix(); } Vec3f NodeSphere::getHandle(int handle, int *constraint , int *field) { *field = 0; float fradius = radius()->getValue(); Vec3f ps; ps.x = fradius; ps.y = fradius; ps.z = fradius; switch (handle) { case STLF: case STLB: return Vec3f(ps) * Vec3f(spereCorners[handle]) * 1.0f; //z-direction case SBRB:case SBLB: return Vec3f(ps) * Vec3f(spereCorners[handle]) * 1.0f; //y-direction case STRB:case SBLF: return Vec3f(ps) * Vec3f(spereCorners[handle]) * 1.0f; //x-direction default: assert(0); return Vec3f(1.0f, 1.0f, 1.0f); } } void NodeSphere::setHandle(int handle, const Vec3f &v) { switch (handle) { case STLF: case STLB: _scene->setField(this, radius_Index(),new SFFloat(v.z*1.0f*Vec3f(spereCorners[handle]).z)); break; case SBRB:case SBLB: _scene->setField(this, radius_Index(),new SFFloat(v.y*1.0f*Vec3f(spereCorners[handle]).y)); break; case STRB:case SBLF: _scene->setField(this, radius_Index(),new SFFloat(v.x*1.0f*Vec3f(spereCorners[handle]).x)); break; } } Node* NodeSphere::toNurbs(int narcslong, int narcslat, int uDegree, int vDegree) { NodeNurbsSurface *node = (NodeNurbsSurface *) _scene->createNode( "NurbsSurface"); float radius = ((SFFloat *) getField(0))->getValue(); /*meaning of most important variables int narcslong ->number of circular arc segments from pole to pole (longitudinal) int narcslat -> number of circular arc segments in lateral direction int vDegree -> degree in direction v, currently limited to 2 int uDegree -> degree in direction u, currently limited to 2 */ int vOrder = vDegree +1; int uOrder = uDegree +1; int i; float arc = 180; Vec3f PS, P1, P2; PS.x = 0; PS.y = -radius; PS.z = 0; P1.x = P2.x = 0; P1.y = P2.y = 0; P1.z = 0; P2.z = 1; NurbsArc tmpArc(narcslong, arc, PS, P1, P2, vDegree); Vec3f *longitudinalArc = new Vec3f[tmpArc.getPointSize()]; float *tmpWeights = new float[tmpArc.getPointSize()]; //load generatrix for (i=0; isetField(node->uDimension_Index(), new SFInt32(uDimension)); node->setField(node->vDimension_Index(), new SFInt32(vDimension)); node->uKnot(new MFFloat(uKnots, uDimension + uOrder)); node->vKnot(new MFFloat(vKnots, vDimension + vOrder)); node->setField(node->uOrder_Index(), new SFInt32(uOrder)); node->setField(node->vOrder_Index(), new SFInt32(vOrder)); node->controlPoint(new MFVec3f(controlPoints, uDimension * vDimension * 3)); node->weight(new MFFloat(weights, uDimension * vDimension)); return node; } Vec3f NodeSphere::getMinBoundingBox(void) { float fradius = radius()->getValue(); Vec3f ret(- fradius, - fradius, - fradius); return ret; } Vec3f NodeSphere::getMaxBoundingBox(void) { float fradius = radius()->getValue(); Vec3f ret(fradius, fradius, fradius); return ret; }