Jump to content

HELP - Rendering sprites misplaced


Vamidi

Recommended Posts

Hi everyone I am tryng to render Spriter images with Opengl. I am using glm as a library to place the object on screen. However if I just take the first zorder and render it with glm by doing it with this code 

 


                            // Prepare transformations            
                            Matrix4 model = glm::mat4(1.0f);

                            // Translate to center
                            model = glm::translate(model, Vector3(parentPos, 0.0f));

                            float deg = pObjectInfo->GetAngleInfo().fAngle;
                            deg *= (pObjectInfo->GetAngleInfo().iSpinDirection) ? -1.0f : 1.0f;

                            // convert to degrees and rotate model
                            model = glm::rotate(model, static_cast<float>(glm::degrees(deg)), glm::vec3(0.0f, 0.0f, 1.0f));

                            // take spriter location and translate based from center of the screen
                            model = glm::translate(model, Vector3(position, 0.0f));

                            //  translate with negative pivot * scale
                            model = glm::translate(model, Vector3(-anchor, 0.0f));

                            // Scale the model with the dimensions of the image
                            model = glm::scale(model, glm::vec3(Vector2{ dest_scale_w, dest_scale_h }, 1.0f));

I hope someone can give clearity on how the positions, pivot  and rotations work in a spriter file. or giving me glm feedback how to solve this.

69327225f9f94b4919e7d7944b1f4124.png
https://gyazo.com/69327225f9f94b4919e7d7944b1f4124

Link to comment
Share on other sites

Hello.  It looks like you're not applying the parent bones to the child objects.  In the scml file (or scon file), you'll see something like this:

<bone_ref id="0" timeline="22" key="2"/>
<bone_ref id="1" parent="0" timeline="23" key="2"/>
<object_ref id="0" parent="0"  timeline="65" key="4" z_index="0"/>
<object_ref id="1" parent="1" timeline="62" key="5" z_index="1"/>

You would have something like an list of transformations.  Take each bone transformation and put it in the list in order, first transforming it by the parent transformation at index 'parent'.   So in this example, you'd put the first bone_ref's transformation at index 0.  The second one (id="1"), you'd transform by the transformation you put at index 0 (since it says parent="0"), and put the result at index 1, and so on.   Each "parent" value refers to the index of transformation you'd use for that bone or object.  The same goes for objects, except you don't need to store their transformations in the list, as the non-bone objects can't have children.

Link to comment
Share on other sites

So if you would only have the loading part implemented which only contains spriterefs, entityrefs and boneref will this still apply? (I removed everything else because of the amount of classes and having my own transformation class) so would you have the same indices for the parent, so for example we take your example and take each bone ref with the parent id. then when I build the matrix I should grab the parentid (and search) and apply those transformations to get it on the right place? Do I understand it correctly?

Link to comment
Share on other sites

16 hours ago, Vamidi said:

So if you would only have the loading part implemented which only contains spriterefs, entityrefs and boneref will this still apply? (I removed everything else because of the amount of classes and having my own transformation class) so would you have the same indices for the parent, so for example we take your example and take each bone ref with the parent id. then when I build the matrix I should grab the parentid (and search) and apply those transformations to get it on the right place? Do I understand it correctly?

Sounds like it.  Your own transformation class would still need to grab the parent and transform using the matrices.  You won't have to search, though, if you use the array/list method.  It's not the parent's id that is given.  It's the parent's index within that list.

Link to comment
Share on other sites

Alright I finally understand what is happening in Spriter sfml version. So basically you have bone_refs and sprite objects. the bones control the images. in order to make it relative to each other you need to calculate all the bones first. When those are caculated you add those values to the sprite object. this will get a sprite position, scale, rotation basically and those values needs to be calculated again to get the right matrix.

--> So basically get the rotation in radians, then rotate and scale it (that is what sfml also does). Multiply the calculated sprite position with the rotation matrix to get the right position. Once that is done make a translation matrix and a scale matrix (scale matrix needed in my case because I am dealing with normalized positions, texcoords in OpenGL). Then multiply in this order to get the model matrix and send that to the gpu.

                    auto rot = glm::rotate(Matrix4(1.0f), angle, Vector3(0.0f, 0.0f, 1.0f));

                    rot = glm::scale(rot, Vector3(m_scale, 1.0f));

                    auto pos = rot * Vector4(-m_origin.x, -m_origin.y, 0.0f, 1.0f);
                    pos += Vector4(m_position, 0.0f, 1.0f);
                    
                    auto trans = glm::translate(Matrix4(1.0f), { pos.x, pos.y, pos.z });

                    auto scale = glm::scale(Matrix4(1.0f), glm::vec3(dimensions, 1.0f));
                    
                    model = trans * rot * scale;

 

result

https://gyazo.com/02580b6038c30ec31e47c7a0daa37cc2

Link to comment
Share on other sites

@lucid I don't know if I should start a new topic, but what do you need to keep in mind when these variables are set to false --> 
bool EditorSettings::reverseYOnLoad = false;
bool EditorSettings::reversePivotYOnLoad = false;
bool EditorSettings::reverseAngleOnLoad = false;

 

because in mine opengl app I have it reversed. Also I am not that great in math, so I dont see what I need to add or decrease to rotate the objects right. I tried to set the variable to false as well in the spriterplusplus example and that is the exact result that I get in mine opengl application.

If you wonder about the matrix is it the same as my previous post.

https://gyazo.com/3f3e855fdb7ab9b6b68281986d5deb48

 

EDIT: I fixed it in a way. I had wrong devices coordinates setup in OpenGL. I see that SFML had it different  so I watched a tutorial about positions and uv coords --> 

after that I saw that my matrix was different again when setting all the reverseYonload etc back to true again. when the matrix was the same everything came together. The only problem is that my animation goes faster everytime (running more than 60fps).

Edited by Vamidi
Fixed issue
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...