GithubHelp home page GithubHelp logo

Comments (13)

guillaumeblanc avatar guillaumeblanc commented on August 22, 2024

Hi,

Glad to hear ozz is helping you. Hope to see what you did with it some day!

Back to your question: ozz::animation::BlendingJob is by design able to blend n layer, n being dynamic. samples uses hard coded number indeed, only to allocate layers though.

ozz::Range is generalising the concept of array using internally a begin and end pointer. It allows to pass BlendingJob an array of layers, without imposing a way to allocate the array. ozz::Range can be initialised from:

So there should be no problem providing a dynamic number of layers. I suspect the issue is in the way you setup ozz::Range. Can you double check that? There might be a bug also, in ozzRange or BlendingJob. So if you're stuck you can send me your BlendingJob setup and array allocation code.

Hope it helps.

Cheers,
Guillaume

from ozz-animation.

syonker avatar syonker commented on August 22, 2024

Thank you so much for the quick response! Below is the code from the blend sample with a minor adjustment. When using the Dynamic Code block it cannot make it through blendingjob's validate function, when using the Sample Code block (the original code) everything runs perfectly. What code would you insert in the Dynamic Code block such that the variable layers can be created based on a dynamic value? Thank you, you're the best!

// Blends animations.
// Blends the local spaces transforms computed by sampling all animations
// (1st stage just above), and outputs the result to the local space
// transform buffer blended_locals_

//----Dynamic Code
	int dynamicNumLayers = kNumLayers;

	ozz::memory::Allocator* allocator = ozz::memory::default_allocator();

	ozz::Range<ozz::animation::BlendingJob::Layer> layers = allocator->AllocateRange<ozz::animation::BlendingJob::Layer>(dynamicNumLayers);
//----Dynamic Code


//----Sample Code
	ozz::animation::BlendingJob::Layer layers[kNumLayers];
//----Sample Code


for (int i = 0; i < kNumLayers; ++i) {
  layers[i].transform = samplers_[i].locals;
  layers[i].weight = samplers_[i].weight;
}

// Setups blending job.
ozz::animation::BlendingJob blend_job;
blend_job.threshold = threshold_;
blend_job.layers = layers;
blend_job.bind_pose = skeleton_.bind_pose();
blend_job.output = blended_locals_;

// Blends.
if (!blend_job.Run()) {
  return false;
}

from ozz-animation.

guillaumeblanc avatar guillaumeblanc commented on August 22, 2024

Hi,

just found the reason: AllocateRange is a C allocator. It works with POD structures, not objects that require their constructors to be called (like ozz::animation::BlendingJob::Layer which sets some default values).

I just realised also that ozz lacks a way to allocate that sort of arrays, like new[] would do. I'll try to provide that and detect non POD structures used with Allocate* functions.

In the meantime you should be able to fix it in you code, using new[], a vector...

That wasn't obvious! Thanks for reporting the issue.

Cheers,
Guillaume

from ozz-animation.

guillaumeblanc avatar guillaumeblanc commented on August 22, 2024

Hi,

I now understand that ozz::memory::Allocator API is error prone, because it exposes object-like allocation functions, but doesn't call constructors/destructors (neither warn about it). It must be fixed.

Have you managed to overcome your issue and blend n layers on your side?

Cheers,
Guillaume

from ozz-animation.

kylawl avatar kylawl commented on August 22, 2024

@syonker if you fully init your layers, you can work around the issue until it's fixed.

for (int i = 0; i < kNumLayers; ++i) {
  layers[i].transform = samplers_[i].locals;
  layers[i].weight = samplers_[i].weight;
  layers[i].joint_weights = ozz::Range<const ozz::math::SimdFloat4>();
}

from ozz-animation.

syonker avatar syonker commented on August 22, 2024

I guess the issue with my work around at the moment is that I'm not declaring 'layers' correctly then. @kylawl how did you declare 'layers' just before that bit of code you sent in order for it to work in the blend sample and by based on a dynamic value? Thank you so much for the help

from ozz-animation.

guillaumeblanc avatar guillaumeblanc commented on August 22, 2024

Hi,

What @kylawl says (thanks BTW) works without changing your allocation strategy. Just add this line to the initialization loop:

for (int i = 0; i < kNumLayers; ++i) {
  layers[i].transform = samplers_[i].locals;
  layers[i].weight = samplers_[i].weight;
  layers[i].joint_weights = ozz::Range<const ozz::math::SimdFloat4>();  // <- Missing initialization workaround
}

BUT, it’s a workaround!

Just to be sure: you don't need to wait for a fix, ozz::animation::BlendingJob and ozz::memory::Allocator are working as expected/documented. The issue is that your allocating your array with a raw memory allocator (à la malloc). This means that ozz::animation::BlendingJob::Layer's are not properly initialized, beacuse their consructors aren't called (thus the workaround). In c++ new/new[] operators should be used to allocate objects/class; that’s one option. I pushed a modified sample to demonstrate it. Another option is using containers like vectors. There are many other options, it's up to you to choose depending on your allocation strategy.

Keep in mind that dynamically allocating is very costly though. It should be avoided during update (ozz does no allocation during update). So I'd recommend to pre-allocate this array, which doesn't prevent you from having dynamic number of layers. Nothing actually prevents you from using a dynamic number of layers...

Hope it helps,
Guillaume

from ozz-animation.

syonker avatar syonker commented on August 22, 2024

Thank you both so much! That's exactly what I needed. By allocating in my init() function with the provided method by the time update() comes around I have a dynamic based number of layers to access and it works perfectly. Ozz is the best, I'm excited to keep working with it!

from ozz-animation.

kylawl avatar kylawl commented on August 22, 2024

from ozz-animation.

guillaumeblanc avatar guillaumeblanc commented on August 22, 2024

Good to hear it's working and that you're happy!

The mix of pod and non-pod types in ozz data structure is part of the confusion. That's also why I think ozz allocation function should handle constructor calls (when needed).

@kylawl, I am curious why you don't allocate the 16 layers on the stack, like ozz sample are doing? It doesn't consume that much stack, and is thread safe by nature.

Looking forward to see what you're doing with ozz.

Cheers,
Guillaume

from ozz-animation.

kylawl avatar kylawl commented on August 22, 2024

I'm using ozz to service a generalized animation system so while this game limits the max layers to 16, it is a configurable maximum within our editor, not necessarily a compile time constant. Hence the heap allocation.

from ozz-animation.

guillaumeblanc avatar guillaumeblanc commented on August 22, 2024

Sounds like an interesting project @kylawl, hope to see it some day!

Looking at ozz Allocator, I saw that typed arrays allocations (those supposed to call constructors) were actually never used by the library, only samples. I presume most users have their own allocator anyway (or use crt). So I removed them, and used vectors in the samples which are safer and easier to read. Here is the change.

from ozz-animation.

kylawl avatar kylawl commented on August 22, 2024

from ozz-animation.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.