void ArticulatedViewer::onGraphics3D(RenderDevice* rd, App* app, const shared_ptr<LightingEnvironment>& lighting, Array<shared_ptr<Surface> >& allSurfaces) {
    // app->gbuffer()->setSpecification(m_gbufferSpecification);
    app->gbuffer()->resize(app->framebuffer()->width(), app->framebuffer()->height());
    app->gbuffer()->prepare(rd, app->activeCamera(), 0, -(float)app->previousSimTimeStep(), app->settings().depthGuardBandThickness, app->settings().colorGuardBandThickness);

    app->renderer()->render(rd, app->framebuffer(), app->depthPeelFramebuffer(), *lighting, app->gbuffer(), allSurfaces);

    Array<Point3> skeletonLines;
    
    m_model->getSkeletonLines(m_pose, m_offset, skeletonLines);
    
    rd->pushState(); {
        rd->setObjectToWorldMatrix(CFrame());
        rd->setDepthTest(RenderDevice::DEPTH_ALWAYS_PASS);
        for (int i = 0; i < skeletonLines.size(); i += 2) {
            Draw::lineSegment(LineSegment::fromTwoPoints(skeletonLines[i], skeletonLines[i + 1]), rd, Color3::red());
        }
    } rd->popState();
    

    //Surface::renderWireframe(rd, posed3D);

    if (m_selectedMesh != NULL) {
        // Find the index array that matches the selected mesh and render it
        for (int p = 0; p < allSurfaces.size(); ++p) {
            const shared_ptr<UniversalSurface>& s = dynamic_pointer_cast<UniversalSurface>(allSurfaces[p]);

            if (s->gpuGeom()->index == m_selectedMesh->gpuIndexArray) {
                // These have the same index array, so they must be the same surface
                s->renderWireframeHomogeneous(rd, Array<shared_ptr<Surface> >(s), Color3::green(), false);
                break;
            }
        }
    }

    float x, y, z, yaw, pitch, roll;
    app->activeCamera()->frame().getXYZYPRDegrees(x,y,z,yaw, pitch, roll);
    screenPrintf("[Camera position: Translation(%f, %f, %f) Rotation(%f, %f, %f)]\n", x,y,z,yaw,pitch,roll);
    screenPrintf("[Shown scaled by %f and offset by (%f, %f, %f)]\n",
                 m_scale, m_offset.x, m_offset.y, m_offset.z);
    
    screenPrintf("Model Faces: %d,  Vertices: %d\n", m_numFaces, m_numVertices);
    if (m_selectedPart != NULL) {
        screenPrintf(" Selected Part `%s', Mesh `%s', Material `%s', cpuIndexArray[%d...%d]\n", 
                     m_selectedPart->name.c_str(), 
                     m_selectedMesh->name.c_str(), 
					 m_selectedMesh->material->name().c_str(),
                     m_selectedTriangleIndex, m_selectedTriangleIndex + 2);
        screenPrintf(" Selected part->cframe = %s\n",
                     m_selectedPart->cframe.toXYZYPRDegreesString().c_str());
    }

    screenPrintf("Hierarchy:");
    // Hierarchy (could do this with a PartCallback)
    for (int i = 0; i < m_model->rootArray().size(); ++i) {
        printHierarchy(m_model, m_model->rootArray()[i], "");
    }
}
static void printHierarchy
(const shared_ptr<ArticulatedModel>& model,
 ArticulatedModel::Part*             part,
 const G3D::String&                  indent) {
    
    screenPrintf("%s\"%s\")\n", indent.c_str(), part->name.c_str());
    for (int i = 0; i < model->meshArray().size(); ++i) {
        if (model->meshArray()[i]->logicalPart == part) {
            screenPrintf("%s  Mesh \"%s\"\n", indent.c_str(), model->meshArray()[i]->name.c_str());
        }
    }

    for (int i = 0; i < part->childArray().size(); ++i) {
        printHierarchy(model, part->childArray()[i], indent + "  ");
    }
}
Exemple #3
0
bool Robot::defineRobot(){
	if(getType() == MOBILE){
		name = "Mobile Robot";
		Leaf *motor1 = new Leaf(0,0, 0,"motor0");
		Leaf *motor2 = new Leaf(1,0, 0,"motor1");
		Leaf *motor3 = new Leaf(2,0, 0,"motor2");
		Leaf *sensor1 = new Leaf(100,0, 0,"sensor1");
		Component *skeleton = new Component("Chasis");
		skeleton->add(motor1);
		skeleton->add(motor2);
		skeleton->add(motor3);
		skeleton->add(sensor1);
		addComponent(skeleton);
		printHierarchy();
		return true;
	}else if(getType() == HUMANOID){
		name = "Humanoid Robot";
		Leaf *motor1 = new Leaf(1,200, 0,"motor1");
		Leaf *motor2 = new Leaf(2,800, 0,"motor2");
		Leaf *motor3 = new Leaf(3,512, 0,"motor3");
		Leaf *motor4 = new Leaf(4,512, 0,"motor4");
		Leaf *motor5 = new Leaf(5,512, 0,"motor5");
		Leaf *motor6 = new Leaf(6,512, 0,"motor6");
		Leaf *motor7 = new Leaf(7,512, 0,"motor7");
		Leaf *motor8 = new Leaf(8,512, 0,"motor8");
		Leaf *motor9 = new Leaf(9,512, 0,"motor9");
		Leaf *motor10 = new Leaf(10,512, 0,"moto10");
		Leaf *motor11 = new Leaf(11,512, 0,"motor11");
		Leaf *motor12 = new Leaf(12,512, 0,"motor12");
		Leaf *motor13 = new Leaf(13,512, 0,"motor13");
		Leaf *motor14 = new Leaf(14,512, 0,"motor14");
		Leaf *motor15 = new Leaf(15,512, 0,"motor15");
		Leaf *motor16 = new Leaf(16,512, 0,"motor16");
		Leaf *motor17 = new Leaf(17,512, 0,"motor17");
		Leaf *motor18 = new Leaf(18,512, 0,"motor18");
		Leaf *sensor100 = new Leaf(100,512, 0,"sensor1");

		Component *chest = new Component("Arm");
		Component *right_arm = new Component("Right Arm");
		Component *left_arm = new Component("Left Arm");
		Component *torax = new Component("Torax");
		Component *right_leg = new Component("Right Leg");
		Component *left_leg = new Component("Left Leg");
		Component *head = new Component("Head");

		head->add(sensor100);
		chest->add(motor1);
		chest->add(motor2);
		right_arm->add(motor3);
		right_arm->add(motor5);
		left_arm->add(motor4);
		left_arm->add(motor6);
		torax->add(motor7);
		torax->add(motor8);
		right_leg->add(motor9);
		right_leg->add(motor11);
		right_leg->add(motor13);
		right_leg->add(motor15);
		right_leg->add(motor17);
		left_leg->add(motor10);
		left_leg->add(motor12);
		left_leg->add(motor14);
		left_leg->add(motor16);
		left_leg->add(motor18);

		addComponent(head);
		addComponent(chest);
		addComponent(right_arm);
		addComponent(left_arm);
		addComponent(torax);
		addComponent(right_leg);
		addComponent(left_leg);
		printHierarchy();
		return true;
	}
	return false;
}
int main(const int argc, const char * argv[])
{
    AppContext ctx;
    if (!appInit(argc, argv, "NTB Widgets Test", 1024, 768, &ctx))
    {
        std::fprintf(stderr, "[APP_ERROR]: Failed to initialize sample app!\n");
        return EXIT_FAILURE;
    }

    ntb::initialize(ctx.shellInterface, ctx.renderInterface);
    {
        bool done = false;
        ntb::GeometryBatch geoBatch;
        ntb::PODArray widgets{ sizeof(ntb::Widget *) };
        ntb::GUI * gui = ntb::createGUI("Sample GUI");

        // Basic blank widget:
        {
            auto w = new ntb::Widget{};
            w->init(gui, nullptr, ntb::Rectangle{ 20, 20, 300, 300 }, true);
            widgets.pushBack(w);
        }

        // A set of buttons:
        {
            MyButtonEventListener buttonEventListener;
            const int buttonIconCount = static_cast<int>(ntb::ButtonWidget::Icon::Count);

            constexpr float btnScale = 1.6f;
            constexpr int btnSize = 50;
            constexpr int xStart  = 350;
            constexpr int yStart  = 20;

            int x = xStart;
            for (int i = 1; i < buttonIconCount; ++i) // Skip fist (Icon::None/0)
            {
                auto btn = new ntb::ButtonWidget{};
                btn->init(gui, nullptr, ntb::Rectangle{ x, yStart, x + btnSize, yStart + btnSize },
                          true, ntb::ButtonWidget::Icon(i), &buttonEventListener);

                btn->setTextScaling(btnScale);
                btn->setState(true);
                x += btnSize + 20; // gap between each (20)

                widgets.pushBack(btn);
            }
        }

        // Title bar & Info bar widgets:
        {
            constexpr int btnOffsX   = 20;
            constexpr int btnOffsY   = 4;
            constexpr int btnSize    = 40;
            constexpr int btnSpacing = 12;

            auto tb = new ntb::TitleBarWidget{};
            tb->init(gui, nullptr, ntb::Rectangle{ 350, 120, 900, 170 }, true,
                     "A title bar - drag me!", true, true, btnOffsX, btnOffsY, btnSize, btnSpacing);

            tb->setTextScaling(1.6f);       // Title bar text
            tb->setButtonTextScaling(1.5f); // Button icon text
            widgets.pushBack(tb);

            auto ib = new ntb::InfoBarWidget{};
            ib->init(gui, nullptr, ntb::Rectangle{ 350, 200, 900, 250 }, true, "Info bar");
            ib->setTextScaling(1.6f);
            widgets.pushBack(ib);
        }

        // List widget:
        {
            auto l = new ntb::ListWidget{};
            l->init(gui, nullptr, ntb::Rectangle{ 20, 350, 300, 500 }, true);
            l->setTextScaling(1.5f);

            l->allocEntries(4);
            l->addEntryText(0, "Hello");
            l->addEntryText(1, "World");
            l->addEntryText(2, "A longer string");
            l->addEntryText(3, "And this one is even longer");

            widgets.pushBack(l);
        }

        // Scrollbar widget:
        {
            auto sb = new ntb::ScrollBarWidget{};
            sb->init(gui, nullptr, ntb::Rectangle{ 550, 300, 600, 600 }, true, 30);
            sb->updateLineScrollState(10, 5);
            widgets.pushBack(sb);
        }

        // Color Picker widget:
        {
            constexpr int colorPickerWidth  = 360;
            constexpr int colorPickerHeight = 500;
            constexpr int xStart = 20;
            constexpr int yStart = 600;

            const ntb::Rectangle rect{ xStart, yStart, xStart + colorPickerWidth, yStart + colorPickerHeight };

            auto cp = new ntb::ColorPickerWidget{};
            cp->init(gui, nullptr, rect, true, 40, 28, 40, 25, 40);
            cp->setTextScaling(1.5f);
            cp->setButtonTextScaling(1.0f);

            widgets.pushBack(cp);
        }

        // 3D view widgets:
        {
            constexpr int view3dWidth  = 450;
            constexpr int view3dHeight = 500;
            constexpr int xStart = 500;
            constexpr int yStart = 650;

            ntb::View3DWidget::ProjectionParameters projParams;
            projParams.fovYRadians      = ntb::degToRad(60.0f);
            projParams.aspectRatio      = 0.0f; // auto computed
            projParams.zNear            = 0.5f;
            projParams.zFar             = 100.0f;
            projParams.autoAdjustAspect = true;

            const int objCount = static_cast<int>(ntb::View3DWidget::ObjectType::Count);

            int x = xStart;
            for (int i = 1; i < objCount; ++i)
            {
                const ntb::Rectangle rect{ x, yStart, x + view3dWidth, yStart + view3dHeight };

                auto v3d = new ntb::View3DWidget{};
                v3d->init(gui, nullptr, rect, true, "3D View Widget", 40, 28, 10, projParams, ntb::View3DWidget::ObjectType(i));
                v3d->setTextScaling(1.5f);
                v3d->setButtonTextScaling(1.0f);
                x += view3dWidth + 50;

                widgets.pushBack(v3d);
            }
        }

        // Var data display widgets inside a window/panel:
        {
            auto varWindow = new ntb::WindowWidget{};
            varWindow->init(gui, nullptr, ntb::Rectangle{ 1000, 20, 1500, 600 }, true, false, "Variables Test", 40, 28, 40, 25);
            varWindow->setTextScaling(1.5f);
            varWindow->setButtonTextScaling(1.0f);

            constexpr int varStartX = 1100;
            constexpr int varStartY = 90;
            constexpr int varWidth  = 300;
            constexpr int varHeight = 50;
            constexpr int varOffsY  = 8;

            ntb::Rectangle rect;
            int y = varStartY;

            auto var0 = new ntb::VarDisplayWidget{};
            rect.set(varStartX, y, varStartX + varWidth, y + varHeight); y += varHeight + varOffsY;
            var0->init(gui, nullptr, rect, true, varWindow, "Var 0");
            var0->setTextScaling(1.5f);
            var0->setButtonTextScaling(1.5f);

            auto var1 = new ntb::VarDisplayWidget{};
            rect.set(varStartX, y, varStartX + varWidth, y + varHeight); y += varHeight + varOffsY;
            var1->init(gui, var0, rect, true, varWindow, "Var 1");
            var1->setTextScaling(1.5f);

            auto var2 = new ntb::VarDisplayWidget{};
            rect.set(varStartX, y, varStartX + varWidth, y + varHeight); y += varHeight + varOffsY;
            var2->init(gui, var0, rect, true, varWindow, "Var 2");
            var2->setTextScaling(1.5f);

            // Change sizes so child vars look nested under the parent
            int cX = varStartX + var0->getExpandCollapseButtonSize();
            int cW = varWidth  - var0->getExpandCollapseButtonSize();

            auto var3 = new ntb::VarDisplayWidget{};
            rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY;
            var3->init(gui, var0, rect, true, varWindow, "Var 3");
            var3->setTextScaling(1.5f);
            var3->setButtonTextScaling(1.5f);

            auto var4 = new ntb::VarDisplayWidget{};
            rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY;
            var4->init(gui, var3, rect, true, varWindow, "Var 4");
            var4->setTextScaling(1.5f);

            cX += var0->getExpandCollapseButtonSize();
            cW -= var0->getExpandCollapseButtonSize();

            auto var5 = new ntb::VarDisplayWidget{};
            rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY;
            var5->init(gui, var3, rect, true, varWindow, "Var 5");
            var5->setTextScaling(1.5f);
            var5->setButtonTextScaling(1.5f);

            auto var6 = new ntb::VarDisplayWidget{};
            rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY;
            var6->init(gui, var5, rect, true, varWindow, "Var 6");
            var6->setTextScaling(1.5f);

            auto var7 = new ntb::VarDisplayWidget{};
            rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY;
            var7->init(gui, var5, rect, true, varWindow, "Var 7");
            var7->setTextScaling(1.5f);

            #if NEO_TWEAK_BAR_DEBUG
            varWindow->printHierarchy();
            std::cout << "\n";
            #endif // NEO_TWEAK_BAR_DEBUG

            // Only have to add the window, since each var widget is a child, directly or indirectly.
            widgets.pushBack(varWindow);
        }

        // Console/terminal window:
        {
            constexpr int maxLines   = 1024;
            constexpr int bufferSize = 2048;

            auto con = new ntb::ConsoleWindowWidget{};
            con->init(gui, nullptr, ntb::Rectangle{ 1550, 20, 2000, 420 }, true, true,
                      "Console Window", 40, 28, 40, 25, maxLines, bufferSize);

            con->setTextScaling(1.3f);
            con->setButtonTextScaling(1.0f);

            ntb::SmallStr line;
            for (ntb::Int64 i = 0; i < 15; ++i)
            {
                line = "Test line ";
                line += ntb::SmallStr::fromNumber(i);
                con->pushLine(line.c_str(), line.getLength());
            }
            con->onAdjustLayout(); // Update the scroll bar for lines out of view

            widgets.pushBack(con);
        }

        // To forward window input events to the widget list.
        ctx.setAppCallback(&ctx, &myAppEventCallback, &widgets);

        while (!done)
        {
            ctx.frameUpdate(&ctx, &done);
            geoBatch.beginDraw();

            // Slider helper (not an actual widget, but used by some widgets):
            {
                static ntb::Float64 sliderPercent = 0.0;

                ntb::ValueSlider slider;
                slider.setRange(0, 100);
                slider.setCurrentValue(sliderPercent);

                slider.drawSelf(geoBatch, ntb::Rectangle{ 650, 350, 950, 400 },
                                ntb::packColor(255, 255, 255), ntb::packColor(255, 100, 0));

                slider.drawSelf(geoBatch, ntb::Rectangle{ 650, 450, 950, 500 },
                                ntb::packColor(255, 255, 255), ntb::packColor(0, 200, 200));

                sliderPercent += 0.2;
                if (sliderPercent > 100.0)
                {
                    sliderPercent = 0.0;
                }
            }

            // Render our widgets:
            widgets.forEach<ntb::Widget *>(
                [](ntb::Widget * widget, ntb::GeometryBatch * batch)
                {
                    widget->onDraw(*batch);
                    return true;
                }, &geoBatch);

            geoBatch.endDraw();
            ctx.framePresent(&ctx);
        }

        widgets.forEach<ntb::Widget *>(
            [](ntb::Widget * widget, void * /*unused*/)
            {
                delete widget;
                return true;
            }, nullptr);
    }
    ctx.shutdown(&ctx);
    ntb::shutdown(); // This will also free the GUI instance.
}
Exemple #5
0
/*=export_func  optionSaveFile
 *
 * what:  saves the option state to a file
 *
 * arg:   tOptions*,   pOpts,  program options descriptor
 *
 * doc:
 *
 * This routine will save the state of option processing to a file.  The name
 * of that file can be specified with the argument to the @code{--save-opts}
 * option, or by appending the @code{rcfile} attribute to the last
 * @code{homerc} attribute.  If no @code{rcfile} attribute was specified, it
 * will default to @code{.@i{programname}rc}.  If you wish to specify another
 * file, you should invoke the @code{SET_OPT_SAVE_OPTS( @i{filename} )} macro.
 *
 * The recommend usage is as follows:
 * @example
 *    optionProcess(&progOptions, argc, argv);
 *    if (i_want_a_non_standard_place_for_this)
 *        SET_OPT_SAVE_OPTS("myfilename");
 *    optionSaveFile(&progOptions);
 * @end example
 *
 * err:
 *
 * If no @code{homerc} file was specified, this routine will silently return
 * and do nothing.  If the output file cannot be created or updated, a message
 * will be printed to @code{stderr} and the routine will return.
=*/
void
optionSaveFile( tOptions* pOpts )
{
    tOptDesc* pOD;
    int       ct;
    FILE*     fp = openSaveFile(pOpts);

    if (fp == NULL)
        return;

    /*
     *  FOR each of the defined options, ...
     */
    ct  = pOpts->presetOptCt;
    pOD = pOpts->pOptDesc;
    do  {
        tOptDesc*  p;

        /*
         *  IF    the option has not been defined
         *     OR it does not take an initialization value
         *     OR it is equivalenced to another option
         *  THEN continue (ignore it)
         *
         *  Equivalenced options get picked up when the equivalenced-to
         *  option is processed.
         */
        if (UNUSED_OPT( pOD ))
            continue;

        if ((pOD->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0)
            continue;

        if (  (pOD->optEquivIndex != NO_EQUIVALENT)
           && (pOD->optEquivIndex != pOD->optIndex))
            continue;

        /*
         *  The option argument data are found at the equivalenced-to option,
         *  but the actual option argument type comes from the original
         *  option descriptor.  Be careful!
         */
        p = ((pOD->fOptState & OPTST_EQUIVALENCE) != 0)
            ? (pOpts->pOptDesc + pOD->optActualIndex) : pOD;

        switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
        case OPARG_TYPE_NONE:
            printNoArgOpt(fp, p, pOD);
            break;

        case OPARG_TYPE_NUMERIC:
            printEntry( fp, p, (void*)(p->optArg.argInt));
            break;

        case OPARG_TYPE_STRING:
            printStringArg(fp, p);
            break;

        case OPARG_TYPE_ENUMERATION:
            printEnumArg(fp, p);
            break;

        case OPARG_TYPE_MEMBERSHIP:
            printSetMemberArg(fp, p);
            break;

        case OPARG_TYPE_BOOLEAN:
            printEntry( fp, p, p->optArg.argBool ? "true" : "false" );
            break;

        case OPARG_TYPE_HIERARCHY:
            printHierarchy(fp, p);
            break;

        case OPARG_TYPE_FILE:
            printFileArg(fp, p, pOpts);
            break;

        default:
            break; /* cannot handle - skip it */
        }
    } while ( (pOD++), (--ct > 0));

    fclose( fp );
}