/* * Copyright (C) 1996, Christopher John Kline * Electronic mail: ckline@acm.org * * This software may be freely copied, modified, and redistributed * for academic purposes and by not-for-profit organizations, provided that * this copyright notice is preserved on all copies, and that the source * code is included or notice is given informing the end-user that the source * code is publicly available under the terms described here. * * Persons or organizations wishing to use this code or any modified version * of this code in a commercial and/or for-profit manner must contact the * author via electronic mail (preferred) or other method to arrange the terms * of usage. These terms may be as simple as giving the author visible credit * in the final product. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * If you use this software the author politely requests that you inform him via * electronic mail. * */ #include #include #include #include #include #include #include #include #include #include class IVSphere { public: IVSphere(SoSeparator *sceneGraph, ObstacleList *olist, Vector center, double radius, SoDrawStyle::Style style = SoDrawStyle::FILLED) { s = new Sphere(center, radius); olist->Add(*s); sp = new SoSphere; sp->radius.setValue(radius); SoTranslation *t = new SoTranslation; t->translation.setValue(center.x, center.y, center.z); d = new SoDrawStyle; d->style.setValue(style); d->lineWidth.setValue(2.0); sh = new SoShapeHints; sh->shapeType = SoShapeHints::SOLID; sh->faceType = SoShapeHints::CONVEX; SoSeparator *r = new SoSeparator; r->addChild(sh); r->addChild(t); r->addChild(d); r->addChild(sp); sceneGraph->addChild(r); } ~IVSphere(void) { delete s; } Sphere *s; private: SoShapeHints *sh; SoDrawStyle *d; SoSphere *sp; SoTranslation *t; SoSeparator *r; }; class IVBox { public: IVBox(SoSeparator *sceneGraph, ObstacleList *olist, Vector tlb, Vector brf, SoDrawStyle::Style style = SoDrawStyle::FILLED) { b = new Box(tlb, brf); olist->Add(*b); double width = tlb.x - brf.x; double height = tlb.y - brf.y; double length = tlb.z - brf.z; sc = new SoCube; sc->width.setValue(fabs(width)); sc->height.setValue(fabs(height)); sc->depth.setValue(fabs(length)); SoTranslation *t = new SoTranslation; Vector center(brf.x + width/2, brf.y + height/2, brf.z + length/2); t->translation.setValue(center.x, center.y, center.z); d = new SoDrawStyle; d->style.setValue(style); d->lineWidth.setValue(2.0); sh = new SoShapeHints; sh->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING; sh->shapeType = SoShapeHints::SOLID; sh->faceType = SoShapeHints::CONVEX; SoSeparator *r = new SoSeparator; r->addChild(sh); r->addChild(t); r->addChild(d); r->addChild(sc); sceneGraph->addChild(r); } ~IVBox(void) { delete b; } Box *b; private: SoShapeHints *sh; SoDrawStyle *d; SoCube *sc; SoTranslation *t; SoSeparator *r; }; class IVBoid : public SimObject { public: IVBoid(SoSeparator *sceneGraph, Vector bPosition, Vector bVelocity, Vector bDimensions) { alreadyAttached = 0; createBoid(bPosition, bVelocity, bDimensions); if (sceneGraph != NULL) { attachAsSubgraph(sceneGraph); } setColor(1.0, 0.0, 0.0); } ~IVBoid(void) { delete boid; } virtual void createBoid(Vector bPosition, Vector bVelocity, Vector bDimensions) { boid = new Boid(bPosition, bVelocity, bDimensions); } virtual bool update(const double &elapsedSeconds) { return boid->update(elapsedSeconds); } virtual void setColor(float r, float g, float b) { IVmaterial->ambientColor.setValue(r, g, b); IVmaterial->diffuseColor.setValue(r, g, b); } virtual void updateGraphics(void) { if (alreadyAttached) { Vector p = boid->getPosition(); IVposition->translation.setValue(p.x, p.y, p.z); IVroll->axis.setValue(SoRotationXYZ::Z); IVpitch->axis.setValue(SoRotationXYZ::X); IVyaw->axis.setValue(SoRotationXYZ::Y); IVroll->angle.setValue(boid->roll); IVpitch->angle.setValue(boid->pitch); IVyaw->angle.setValue(boid->yaw); } } Boid *boid; protected: virtual void attachAsSubgraph(SoSeparator *root) { if (alreadyAttached) return; IVsep = new SoSeparator; IVsep->renderCaching.setValue(SoSeparator::OFF); IVsep->boundingBoxCaching.setValue(SoSeparator::OFF); IVsep->renderCulling.setValue(SoSeparator::OFF); IVsep->pickCulling.setValue(SoSeparator::OFF); IVposition = new SoTranslation; IVroll = new SoRotationXYZ; IVpitch = new SoRotationXYZ; IVyaw = new SoRotationXYZ; IVroll->axis.setValue(SoRotationXYZ::Z); IVpitch->axis.setValue(SoRotationXYZ::X); IVyaw->axis.setValue(SoRotationXYZ::Y); IVroll->angle.setValue(boid->roll); IVpitch->angle.setValue(boid->pitch); IVyaw->angle.setValue(boid->yaw); // Add an object to represent the boid SoSeparator *broot = new SoSeparator; IVmaterial = new SoMaterial; IVmaterial->specularColor.setValue(.5, .5, .5); IVmaterial->shininess.setValue(0.2); IVmaterial->diffuseColor.setValue(1.0, 1.0, 1.0); IVmaterial->ambientColor.setValue(1.0, 1.0, 1.0); broot->addChild(IVmaterial); SoScale *sc = new SoScale; Vector d = boid->getDimensions(); sc->scaleFactor.setValue(d.x, d.y, d.z); broot->addChild(sc); if (IVBoid::boidModel == NULL) { IVBoid::boidModel = IVBoid::loadModel("./boid.iv"); } if (IVBoid::boidModel != NULL) { broot->addChild(IVBoid::boidModel); } else { SoSphere *bsphere = new SoSphere; bsphere->radius.setValue(1.0); broot->addChild(bsphere); } IVsep->addChild(IVposition); IVsep->addChild(IVyaw); IVsep->addChild(IVpitch); IVsep->addChild(IVroll); IVsep->addChild(broot); root->addChild(IVsep); alreadyAttached = 1; } static SoSeparator *loadModel(char *name) { static SoSeparator *model = NULL; // read in the file for the first time if (model == NULL) { // open input file SoInput sceneInput; if (!sceneInput.openFile(name)) { cerr << "Can't find file \"" << name << "\"" << endl; return NULL; } // read in whole file model = SoDB::readAll(&sceneInput); if (model == NULL) { cerr << "Problem occurred when reading file \"" << name << "\" \n"; return NULL; } sceneInput.closeFile(); } return model; } private: SoSeparator *IVsep; SoTranslation *IVposition; SoRotationXYZ *IVroll; SoRotationXYZ *IVpitch; SoRotationXYZ *IVyaw; SoMaterial *IVmaterial; int alreadyAttached; static SoSeparator *boidModel; };