Jump to content

  • Log In with Google      Sign In   
  • Create Account


Danicco

Member Since 18 Jan 2011
Offline Last Active Jun 03 2014 03:18 PM

Topics I've Started

OpenGL UV Mapping and FBX Loading

22 March 2014 - 05:13 PM

I'm reading the FBX file format and getting the UVs from the models, but I'm having weird issues with the UV Mapping from the textures.

 

Also, I'm using the sbti_image loader to load a PNG file, not sure if it's relevant (I think it reverses the pixels but I think that's common for all image types).

 

So, when I load a 2D Image, using a texture I have the image mirrored both in horizontal and vertical. That was fine if I just reversed the positions and mirror the texture, but that only works when the texture is full. I didn't want to keep that as a "fix" so I tried to get the correct orientation from the FBX and apply it properly.

 

The 2nd image is how it is in the 3DS Max, in the first image is how my engine is displaying it.

 

Example_zps3765bc58.jpg

 

I'm reversing the V component so the texture is at least correct vertically:

for(int i = 0; i < totaUVs; i++)
{
    float u = UVs[uIndex];
    float v = UVs[uIndex + 1];
    
    UVs[uIndex] = u;
    UVs[uIndex + 1] = 1.0f - v;			
}

If I don't do this, the image is also mirrored upside down.

The "1.0f - v" part is correcting the V part, but the U is still incorrectly mapped. I can't do "1.0f - u" because then the U part would be reversed in the image, so in an image of 200 pixels width, a U part of 10 would be 190, meaning it works if the image is full (100% width and 100% height) but not when I'm using a mapped texture like this.

 

How can I solve this?

I'm thinking in reversing the pixels in my image data but if possible I'd like to find a "smarter" solution, any help with this?


Skeletal Animation System

11 March 2014 - 09:15 AM

Hi, I'm coding my skeletal animation system for my engine and I'm not really sure what and how I'm supposed to do what I need to do... I have a vague idea, but I can't really put it into the code in a way that I like. I'm having trouble with both the concept and technical parts of it.

 

I have this structure:

class KeyFrame
{
    public:
        unsigned int keyFrame;
        Vector3 keyValues;
};

class Bone
{
    public:
        //Other stuff to deal with hierarchy

        vector<KeyFrame*> keyTranslates;
        vector<KeyFrame*> keyRotates;
};

class Track
{
    public:
        wstring trackName;
        bool trackLoop;
        unsigned int frameStart;
        unsigned int frameEnd;
};

class Skeleton
{
    public:
        vector<Track*> tracks;
        vector<Bone*> bones;

        //skeleton data here
        float boneTranslations[MAX_BONES * 3]; //vec3 trans
        float boneRotations[MAX_BONES * 4]; //quat rots
};

I'm already loading the data I want, so I have something like "Bone01: keyFrame 5 > TranslateX 0.5, keyFrame 10 > TranslateX -0.5" etc

Each model has a pointer to a skeleton, who has a collection of bones, and I define tracks:

class Model
{
    public:
        Skeleton* skeleton;
        Track* currentTrack; //current playing track
};

//Game Start
Model* myModel = Resources.Load("myModelName");
myModel->skeleton = Resources.Load("mySkeletonName");

//Skeleton::AddTrack(wstring trackName, uint frameStart, uint frameEnd, bool trackLoop);
myModel->skeleton->AddTrack(L"WALK", 5, 10, true);

//Setting this model's current track as WALK
myModel->SetTrack(L"WALK");

So, first I think I need to change the "current track" to support multiple tracks to compose animations (such as WALK + ATTACK) right?

 

Then the problem I'm having most is figuring my "Update Skeleton" function:

void Model::Draw(Camera* camera, float& interpolation)
{
    Shader* shader = material->GetShader();

    skeleton->UpdateSkeleton(currentFrame); //this

    meshSkin->Activate(shader);
    mesh->Render(shader);
    meshSkin->Deactivate(shader);
}

void Skeleton::Update(uint currentFrame)
{
    for(uint i = 0; i < bones.size(); i++)
    {
        //checking ALL translates for that bone
        for(uint j = 0; j < bones[i]->keyTranslates.size(); j++)
        {
            //what should I do here?
            //check if this keyFrame value is higher or equal than currentFrame, then loop again
            //to search for the previousKeyFrame (if it has one), then interpolate between the two, 
            //then interpolate again to find the middle (currentFrame)?
            //And where/how does deltaTime fits into this? Maybe having a previousFrame as well?

            //Actually, scratch this, this seems bad to do at every render call, 
            //I'd like to avoid doing this if I can and "remember" the animation motion I'm currently at 
            //for that model so I can skip this operation.
            //...or a clever way to handle this
        }
        
        //Now check for rotations as well...
        for(uint j = 0; j < bones[i]->keyRotates.size(); j++)
        {}
    }
}

I'm trying to save these operations by remembering the motion I was, but then I'd need to save in the model, for each bone, the previous keyFrame and the next keyFrame for all of them. And I would only need to figure the next motion when I reach the "nextKeyFrame". But this means basically having a copy of the skeleton's bones in the model... not sure if I should go this way.

 

I've been thinking since yesterday but I can't figure how should I proceed from here... any help?


Porting C++ to Android

28 February 2014 - 01:45 PM

I am coding a game engine and I'm trying to port it to Android to check for errors and tests.

But I still haven't even been able to get a simple function working...

 

I'm following a few tutorials and I think I know what I am supposed to do:

 

- Put my C sources in my android project's JNI folder.

- Build it with the Android NDK, after setting everything up.

- Link the lib on my Activity class, call a method, crash.

 

My C source looks like this:

#include <jni.h>

jint Java_my_engine_test_MainActivity_MyFunctionName(JNIEnv* env, jobject obj)
{
    return 0;
}

My Android.mk is:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := EngineTest
LOCAL_SRC_FILES := EngineTest.c

include $(BUILD_SHARED_LIBRARY)

And my Java file is:

package my.engine.test;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //If I uncomment this line, the app crashes, else it's ok
        //int a = MyFunctionName();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private native int MyFunctionName();
    
    static {
        System.loadLibrary("EngineTest");
    }
}

So I've made certain that the function name is according to the specification (Java, package name, class name, then function name) and that I'm using JNI types, and it's a really really really simple function.

 

Also, for some reason, none of the examples that came with the NDK build for me when using the Eclipse NDK support. I get syntax errors (syntax!). So I'm guessing they must've changed it somewhere along the way...

 

I'm at a loss, I've been looking all over for what could be causing this and how I can get a simple C function to work in the Android Emulator, but found nothing so far. I'm still checking other tutorials and following them but they're all the same thing and have the same errors, so I'm guessing it must be something else.

 

I've also set up the NDK folder in Eclipse and now it's auto-building my C sources every time, and it builds, but the app simply crashes when I try to access a function from the lib.

 

Does anyone know what could be causing this?

 

Also, a question, the engine's nearly finished for a first project and I made it with certain rules that I'd like to ask about when porting to Android.

I've made it a single class containing everything to run a game, and a few classes available to the game code such as Image, Models, Animations, etc.

There's only one rule that the game code must abide to and that is to inherit the "GameState" class (abstract) so it forces implementations of the methods required for the engine to run (Start, Pause, Resume, Update, Exit functions).

 

I was thinking in having the engine and making the game elsewhere, like Java (when I get the engine working) for faster coding, but then there's the problems of the C++ classes (Image, Models etc) that probably won't be available on Java (although this I can fix with a wrapper), and the GameState class that a state must inherit to set it to the engine. I don't think I can wrap this last one and I'm don't know how to proceed with this.

 

If there's no way, I'll probably try coding the entire game in C++ and trying to port it all at once... if only I can get this NDK to work...

 

Thank you in advance.


Camera Matrix, GLM and Rotations with Quaternions

24 February 2014 - 03:07 PM

I have a Camera class like this:

class Camera
{
    public:
        Matrix4x4& GetMatrix(float& interpolation); 
    private:
        Vector3 _cameraPosition;
        Vector3 _cameraTarget;
        Vector3 _cameraOrientation;

        Vector3 _cameraForward;
        Vector3 _cameraUp;
        Vector3 _cameraRight;

        Matrix4x4 _cameraMatrix;
};

And GetMatrix(interpolation) does this:

Matrix4x4& Camera::GetMatrix(float& interpolation)
{
    Vector3 currentPosition;
    currentPosition.x = _cameraPosition.x + ((cameraPosition.x - _cameraPosition.x) * interpolation);
    currentPosition.y = _cameraPosition.y + ((cameraPosition.y - _cameraPosition.y) * interpolation);
    currentPosition.z = _cameraPosition.z + ((cameraPosition.z - _cameraPosition.z) * interpolation);

    Vector3 currentTarget;
    currentTarget.x = _cameraTarget.x + ((cameraTarget.x - _cameraTarget.x) * interpolation);
    currentTarget.y = _cameraTarget.y + ((cameraTarget.y - _cameraTarget.y) * interpolation);
    currentTarget.z = _cameraTarget.z + ((cameraTarget.z - _cameraTarget.z) * interpolation);

    _cameraMatrix[0][0] = 1.0f;
    _cameraMatrix[1][1] = 1.0f;
    _cameraMatrix[2][2] = 1.0f;
    _cameraMatrix[3][3] = 1.0f;

    _cameraForward = Math::Normalize(currentTarget - currentPosition);
    _cameraUp = Math::Normalize(cameraOrientation);
    _cameraRight = Math::Normalize(Engine::Math::Cross(_cameraForward, _cameraUp));
    _cameraUp = Math::Cross(_cameraRight, _cameraForward);

    _cameraMatrix[0][0] = _cameraRight.x;
    _cameraMatrix[1][0] = _cameraRight.y;
    _cameraMatrix[2][0] = _cameraRight.z;

    _cameraMatrix[0][1] = _cameraUp.x;
    _cameraMatrix[1][1] = _cameraUp.y;
    _cameraMatrix[2][1] = _cameraUp.z;

    _cameraMatrix[0][2] = -_cameraForward.x;
    _cameraMatrix[1][2] = -_cameraForward.y;
    _cameraMatrix[2][2] = -_cameraForward.z;

    _cameraMatrix[3][0] = -Math::Dot(_cameraRight, currentPosition);
    _cameraMatrix[3][1] = -Math::Dot(_cameraUp, currentPosition);
    _cameraMatrix[3][2] = Math::Dot(_cameraForward, currentPosition);

    return _cameraMatrix;
}

The GetMatrix() function is from GLM, with the interpolation part that I added.

It works perfectly for tests and such, by setting the _cameraTarget and _cameraPosition.

 

I'm adding camera controls and this is where I'm getting problems. I'm adding rotation to the camera but it's not working as expected... what I tried:

void Camera::RotateAroundY(float angleDegrees)
{
    float angleRadians = angleDegrees * (PI / 180);

    float cAngle = cosf(angleRadians/2);
    float sAngle = sinf(angleRadians/2);
		
    Quaternion tRotation;
    tRotation.w = cAngle;
    tRotation.x = 0;
    tRotation.y = sAngle;
    tRotation.z = 0;

    //Finding the rotated direction of my camera
    _cameraDirection = (cameraTarget - cameraPosition) * tRotation; //Vector3 * Quaternion

    //Setting it back to cameraTarget as well
    cameraTarget = cameraPosition + _cameraDirection;
}

With also a RotateAroundX function.

Standing still at 0,0,0, these functions work well alone. If I use only RotateAroundY I can navegate around and I didn't noticed anything wrong. Same for X.

The problem starts when I try to combine both, the movement gets really weird... If I'm looking to the right from the Origin (1, 0, 0), the Look Up/Down doesn't move at all. When I'm looking to the back (0, 0, 1), the Up/Down rotation is inversed.

 

I was calculating the rotation not when the functions are called but after, so I just stored them in a Vector3 rotation, and then calculated a single Quaternion with the GLM Quaternion from Vector3 (euler angles), but I started getting this result, so I separated them in two function to try to pinpoint the issue but I still can't figure why.

 

I managed to get around this by creating a new Vector3 called "direction" which I calcule every time the rotation changes with:

_camera.directionY = sin(_camera.rotationX * 3.1415/180);		
_camera.directionX = sin(_camera.rotationY * 3.1415/180) * cos(_camera.rotationX * 3.1414/180);
_camera.directionZ = cos(_camera.rotationX * 3.1415/180) * cos(_camera.rotationY * 3.1415/180); 

But I have to constantly check if rotationX/Y >= 360, and I'd like to keep using the Quaternion and LookAt functions from GLM...

 

Any ideas on how I can solve this?


How to deal with Input Sequences?

23 February 2014 - 03:21 PM

I'm coding the Input part of an engine and this is the "flow" of command:

 

1. (Startup) GameCode defines Commands such as MOVE_LEFT, MOVE_RIGHT

- This command is saved in a vector _commandList

 

2. OS sets the values via the Input class by passing an Input ID and Value

- This changes depending on the OS, so the programmer just have to call the input methods to set values to keys

 

3. Whenever the OS sets a new value by Input ID, the Input checks if there's a command assigned to it, if there is, it adds a new element in a vector specifying everything

- This is where the issue is, I'm using new everytime

 

4. During the Game Loop, before the Update(), I check all values in this vector (InputQueue) and update the _commandList current state.

- After this the Update() loop will have a list of all commands and their state during that time

 

It's working fine for key presses and such, since there's only a few commands to each game. But now I added the movement X/Y input code and the InputQueue vector is growning HUGE when I move the mouse.

In the Input Update function I do remove inputs after a time, but I'm worried that when I move the mouse, on Windows, I get a message for every pixel I moved the mouse to.

So if I move the mouse 10 pixels left, I get 10 messages and that's 10 new inputQueues, 10 new checks, and 10 new deletes... if it's half a 1920 screen, that's 1000 news and deletes and I that seems worrisome...

 

So I'd like to remove this new/delete in this function since it's called thousands of time per second so I was thinking in moving to an array of fixed size, but then there's the cons of iterating over all elements in the array instead of a dynamic vector one, and that I don't know how to deal with moving elements in the array.

 

This is how it is currently:

vector<Command*> _commandList; //commands that will be defined per game
vector<InputQueue*> _inputQueue; //vector to hold all input to be processed in the next UPDATE
InputKeys _inputKeys[300]; //each one of these has 3 float values

//function when any input from the OS comes to the engine
void Input::SetInput(int inputCode, float valueX, float valueY, float valueZ)
{
    //Defining the inputKey values
    inputKeys[inputCode].valueX = valueX;
    inputKeys[inputCode].valueY = valueY;
    inputKeys[inputCode].valueZ = valueZ;

    //If there's a game command assigned to this input
    //Add a new input to the queue to be processed in the next main Update()
    if(inputKeys[inputCode].command != 0)
    {
        InputQueue* newInput = new InputQueue();
        newInput->valueX = inputKeys[inputCode].valueX;
        newInput->valueY = inputKeys[inputCode].valueY;
        newInput->valueZ = inputKeys[inputCode].valueZ;
        newInput->command = inputKeys[inputCode].command;
        newInput->time = timeModule.GetRealTime();

        _inputQueue.Add(newInput);
    }
}

//function called right before the main GAME CODE update
//I update all the game commands' states so the GAME CODE can use them
void Input::Update(uint64 currentTime)
{
    for(uint i = 0; i < _inputQueue.size(); i++)
    {
        if(_inputQueue[i]->time <= currentTime - inputTimeOnQueue)
        {
            delete _inputQueue[i];
            _inputQueue.erase(_inputQueue.begin() + i, _inputQueue.begin() + i + 1);
            i--;
            continue;
        }

        if(_inputQueue[i]->inputTime >= _lastUpdate && _inputQueue[i]->inputTime <= currentTime)
        {
            Command* command = _inputQueue[i]->command;
            //update the command state
            command->valueX = _inputQueue[i]->valueX;
            //etc
        }
    }
    _lastUpdate = currentTime;
}

After this, during the main Update I can check the _commandList values and they'll be updated ready for checking.

I'd like to change it to something like this:

vector<Command*> _commandList; //commands that will be defined per game
InputQueue _inputQueue[20]; //I set a maximum of 20 input queues per update - anymore and I'll erase the older ones
InputKeys _inputKeys[300]; //each one of these has 3 float values

//function when any input from the OS comes to the engine
void Input::SetInput(int inputCode, float valueX, float valueY, float valueZ)
{
    //Defining the inputKey values
    inputKeys[inputCode].valueX = valueX;
    inputKeys[inputCode].valueY = valueY;
    inputKeys[inputCode].valueZ = valueZ;

    //If there's a game command assigned to this input
    //Add a new input to the queue to be processed in the next main Update()
    if(inputKeys[inputCode].command != 0)
    {
        //I need to figure how to get this ? - probably an int and I'll check if it's 20 or > and reset to 0 if is
        _inputQueue[?]->valueX = inputKeys[inputCode].valueX;
        //etc
    }
}

//function called right before the main GAME CODE update
//I update all the game commands' states so the GAME CODE can use them
void Input::Update(uint64 currentTime)
{
    for(uint i = 0; i < 20; i++)
    {
        if(_inputQueue[i].time <= currentTime - inputTimeOnQueue)
        {
            //need to figure how to check current to last, considering the current might be 0~20
            //and break so I don't loop through all 20 when it's not needed (not sure if I need to worry about this)
        }

        if(_inputQueue[i].inputTime >= _lastUpdate && _inputQueue[i].inputTime <= currentTime)
        {
            Command* command = _inputQueue[i].command;
            //update the command state
            command->valueX = _inputQueue[i].valueX;
            //etc
        }
    }
    _lastUpdate = currentTime;
}

Any suggestions on how can I get this to work or any other way to handle this?


PARTNERS