About Store Forum Documentation Contact



Post Reply 
Mesh scaling within a ViewPort
Author Message
phleshdef Offline
Member

Post: #1
Mesh scaling within a ViewPort
Greetings.

I'm continuing my efforts to create an inventory GUI for my little project. I've successfully been able to use a ViewPort to provide a sort of character preview in the inventory menu. I've been able to accomplish this by following poster Rabishan's example found here:

http://www.esenthel.com/community/showth...t=viewport

Right now I'm attempting to show the equipped items in the preview screen. However, I've ran into some trouble getting an item to scale correctly. I imagine I'm doing something moronic.

Here are the snippets of the relevant code.

Code:
STRUCT(InventoryWindow, GuiObjs)
//{
    GuiObjs guiObjects;

    Window *window;

    Region *listRegion;
    Region *previewRegion;

    Viewport *characterViewPort;
    CSkeleton cskel;     
    MeshPtr mesh, armor, pants, boots, gauntlets, leftHand, rightHand;
    
    Color GridTextColor;

    List<LysianItem> invItems;
    bool IsShowing;

    void Create();
    void Show();
    void Hide();
    void Toggle();
    void InputListen();
    void Update(int);
    void Draw();
    void UpdateMeshes();

    static void InventoryWindow::Render()
    {
        switch(Renderer())
        {
            case RM_PREPARE:

                InventoryMenuWindow.mesh->draw(InventoryMenuWindow.cskel);
                
                if(Players[0].inventory.slot[SLOT_ARM_R].valid())
                {
                    if(C OrientP *point = InventoryMenuWindow.cskel.findPoint("HandR"))
                    {
                        Matrix handRMatrix;
                        handRMatrix.setPosDir(point->pos, point->cross(), point->dir);
                        handRMatrix.scale(Players[0].inventory.slot[SLOT_ARM_R]().scale);
                        InventoryMenuWindow.rightHand->draw(handRMatrix);                        
                    }
                }

                break;
        }
    }


    static void InventoryWindow::CharacterViewportDraw(Viewport &viewport)
    {
        Int cameraIndex = Mid((UIntPtr)viewport.user, 0, Elms(CameraList)-1);
        CameraList[cameraIndex].set();
        Renderer(Render);
        SetMatrix(MatrixIdentity);
    }

} extern InventoryMenuWindow;

Code:
void InventoryWindow::Create()
{
    if(guiObjects.load("../Game Files/GUI Forms/Inventory.gobj"))
    {
        window = &guiObjects.getWindow("winInventory");
        listRegion = &guiObjects.getRegion("regInventoryList");
        characterViewPort = &guiObjects.getViewport("vpCharacter");

        characterViewPort->user = (Ptr)1;

        window->style = &GlobalGUIStyles.MenuWindowStyle;
        window->hide();

        GridTextColor = WHITE;

        IsShowing = false;
        Gui += guiObjects;
    }
}

void InventoryWindow::Show()
{
    if(!IsShowing)
    {
        ListColumn list_column[] =
        {
            ListColumn(MEMBER(LysianItem, name), 0.3f, L"Name"),
            ListColumn(MEMBER(LysianItem, damage), 0.3f, L"Damage"),
            ListColumn(MEMBER(LysianItem, value), 0.3f, L"Value")
        };

        *listRegion += invItems.create(list_column, Elms(list_column)).setData(Players[0].inventory.items);

        characterViewPort->draw_func = CharacterViewportDraw;
        UpdateMeshes();

        GlobalGUIStyles.InitStyles();

        invItems.back_color = GlobalGUIStyles.MenuBackColor;
        //invItems.setElmTextColor(MEMBER(InventoryWindow, GridTextColor));

        for(int colIndex = 0; colIndex < invItems.columns(); colIndex++)
        {
            invItems.column(colIndex).button.color = GlobalGUIStyles.MenuBackColor;
            invItems.column(colIndex).button.tds->color = GlobalGUIStyles.MenuTextColor;
        }

        CameraList[1].yaw = 3.155f;
        CameraList[1].setSpherical();
        cskel.clear().animate(L"../data/anim/stand.anim", Time.time()).updateMatrix(MatrixIdentity).updateVelocities();
        
        Ms.visible(true);
        window->show();
        IsShowing = true;
    }
}



void InventoryWindow::UpdateMeshes()
{
    mesh = "../Data/obj/Chr/Human/0.mesh";
    rightHand = Players[0].inventory.slot[SLOT_ARM_R]().meshPath;

    cskel.create(Skeletons("../Data/obj/Chr/Human/0.skel"));
}

The above code is producing the result as shown in the attached screenshot. Any thoughts on what I may be doing wrong here are, as always, greatly appreciated.


Attached File(s) Image(s)
   
09-29-2012 10:38 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #2
RE: Mesh scaling within a ViewPort
handRMatrix.scale(Players[0].inventory.slot[SLOT_ARM_R]().scale); It looks to me like this is where you are drawing the club. Is that matrix set to the right scale? What happens if you use MatrixIdentity? Better yet, draw the club using the same scale that the guy is being drawn with.

Most likely, it's an issue with having drawn them using 2 different scales.
09-29-2012 11:20 PM
Find all posts by this user Quote this message in a reply
phleshdef Offline
Member

Post: #3
RE: Mesh scaling within a ViewPort
Well, I was attempting to draw it at the same scale of the actual club item thats in the players inventory.

I suppose its possible that maybe the mesh for the players body I'm using in the preview window is being drawn at a smaller scale than the actual player in game is being drawn at?

In either event, I'll play around with some of the ideas you threw out there. Thanks very much for your thoughts.
09-29-2012 11:30 PM
Find all posts by this user Quote this message in a reply
phleshdef Offline
Member

Post: #4
RE: Mesh scaling within a ViewPort
Ah, I actually made a little progress.

I adjusted the following functions in the above code:

Code:
void InventoryWindow::UpdateMeshes()
{
    mesh = "../Data/obj/Chr/Human/0.mesh";
    rightHand = Players[0].inventory.slot[SLOT_ARM_R]().meshPath;
    cskel.create(Skeletons("../Data/obj/Chr/Human/0.skel"),  Players[0].cskel.scale());
}

Code:
    static void InventoryWindow::Render()
    {
        switch(Renderer())
        {
            case RM_PREPARE:
                
                
                if(Players[0].inventory.slot[SLOT_ARM_R].valid())
                {
                    if(C OrientP *point = InventoryMenuWindow.cskel.findPoint("HandR"))
                    {
                        InventoryMenuWindow.rightHand->draw(Matrix().setPosDir(point->pos, point->cross(), point->dir).scale(Players[0].inventory.slot[SLOT_ARM_R]().scale));                        
                    }
                }
                
                InventoryMenuWindow.mesh->draw(InventoryMenuWindow.cskel);

                break;
        }    
    }

Basically, I needed to set the scale of cskel to match that of the player whenever I create it in the viewport. It works pretty decent. The only problems I'm having now is the club isn't quite attaching correctly to the hand in the character preview. Its a little to the left of it instead of actually in it. Thats strange because its virtually the same code that is used to attach it to the player's hand whenever its equipped on the real player, and it works correctly there. So theres that, and I'd like to figure out how to get those darn clouds out of the viewport (and maybe just put a black background color behind it).

Making progress though. =)
(This post was last modified: 09-30-2012 07:57 AM by phleshdef.)
09-30-2012 07:56 AM
Find all posts by this user Quote this message in a reply
phleshdef Offline
Member

Post: #5
RE: Mesh scaling within a ViewPort
Going back to what I said in my previous post. It seems like, if I scale the club mesh in the viewport the same as the right hand inventory item and I create the cskel in the viewport the same as the players cskel, then everything is the right size.

The problem though, is the club isn't quite in the characters hand in the view port. Now if I don't scale the club at all, its in his hand, but its way huge, like in the screenshot above.

I think whats happening is, I'm attaching the club to his hand, but then when it gets scaled down, its back out of his hand because it got attached at the larger scale.

I tried scaling it first, then attaching it, but that seems to result in the scaling getting reset back to the larger size. Any ideas on that?
09-30-2012 06:55 PM
Find all posts by this user Quote this message in a reply
phleshdef Offline
Member

Post: #6
RE: Mesh scaling within a ViewPort
Nevermind, I think I got it!

Code:
InventoryMenuWindow.rightHand->draw(Matrix().setPosDir(point->pos, point->cross(), point->dir).scaleOrn(Players[0].inventory.slot[SLOT_ARM_R]().scale));

Using scaleOrn() istead of scale() to size the club down seems to do the trick perfectly.
(This post was last modified: 10-01-2012 12:59 AM by phleshdef.)
10-01-2012 12:44 AM
Find all posts by this user Quote this message in a reply
phleshdef Offline
Member

Post: #7
RE: Mesh scaling within a ViewPort
This is all working much better for me now. If someone could tell me an easy way to get rid of the sky in the viewport and just have a black background, I'd be one happy camper.
10-01-2012 06:36 AM
Find all posts by this user Quote this message in a reply
phleshdef Offline
Member

Post: #8
RE: Mesh scaling within a ViewPort
Ah, finally figured out the concept of drawing a reverse box mesh with a texture which solves my sky problem. Tutorials are awesome once you figure out the right one to look at.
10-01-2012 08:52 PM
Find all posts by this user Quote this message in a reply
Post Reply