0

I'm working on a three_js project, but it's the Flutter package three_js, not the JavaScript module three.js. Recently I've been converting some JavaScript code to Flutter using three_js, and I can't figure out how to set a buffer geometry attribute. Here's the JavaScript:

const g = new THREE.BufferGeometry();

g.setAttribute(
  'position',
  new THREE.BufferAttribute(new Float32Array(this.branches.verts), 3),
);

g.setAttribute(
  'normal',
  new THREE.BufferAttribute(new Float32Array(this.branches.normals), 3),
);

g.setAttribute(
  'uv',
  new THREE.BufferAttribute(new Float32Array(this.branches.uvs), 2),
);

g.setIndex(
  new THREE.BufferAttribute(new Uint16Array(this.branches.indices), 1),
);

The first thing that caught me by surprise was the order of function parameters, I looked at the source code and found this function syntax: BufferGeometry setAttribute(Attribute type, dynamic attribute), which switches the parameters as compared to the JavaScript version. Now of course, I should expect some changes in code when comparing a port from one language to another, for multiple reasons, so this wasn't too weird. Quick fix, all I have to do is switch the order of my parameters, right? Nope. I switched the order, then realized I had a bigger problem.

When I tried to initialize the class Attribute, this is what VS Code said to me: "Generative enum constructors can only be used as targets of redirection." I'm not quite sure what that means, but I thought I might be able to get away with just using BufferAttribute and then type casting...but BufferAttribute is apparently an abstract class, so I went with Float32BufferAttribute (and Uint16BufferAttribute), and then type casted, like this:

g.setAttribute(
  three.Float32BufferAttribute(three.Float32Array.fromList(normals), 3) as three.Attribute,
  'normal'
);

This made the errors go away, but it also didn't work, since it didn't apply correctly to the screen when I ran it.

At this point, I'm looking for someone who knows what all of this means, and what the correct syntax of the function is. Given that three_js is a port from three.js, it's not as commonly known in the developer community, and therefore there aren't as many answers to my questions.

Note: I realize that copying directly from JavaScript isn't optimized or good practice, but please ignore it for the sake of the question being asked.

1 Answer 1

2

From the documentation, the order doesn't appear to have changed at all. You have simply misunderstood the purpose of the Attribute type of the first parameter.

Here, Attribute is an enum to replace the magic string that Three.JS uses (or union type if you're using the Typescript definitions). So instead of setAttribute('position', ...) you would use setAttribute(Attribute.position, ...). You would then pass the corresponding BufferAttribute object to the second dynamic parameter (which should really be better documented, but I guess they are depending on you consulting the Three.JS documentation and performing the necessary conversions yourself).

So the Dart version of:

g.setAttribute(
  'position',
  new THREE.BufferAttribute(new Float32Array(this.branches.verts), 3),
);

should be:

g.setAttribute(
  Attribute.position,
  three.Float32BufferAttribute(three.Float32Array.fromList(verts), 3),
);
// OR
g.setAttribute(
  Attribute.position,
  three.Float32BufferAttribute.fromList(verts, 3),
);

Alternatively, you could use setAttributeFromString to get a more similar syntax to the JS version, but I wouldn't recommend that if at all possible.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, I've been trying to figure this out for a while! I'm a little confused about your first Dart conversion though, since three.BufferAttribute() is an abstract class in the Flutter conversion, we can't instantiate it, so I would think that only the second example you gave would be correct, right?
@5rod You are correct. I missed the abstract label in the documentation.
Thanks! They really need to increase the clarity of some of these functions, I’ve been stuck on this for a while.
@5rod While true, keep in mind that the library you are using is currently version 0.0.6 and is little more than a direct one-to-one port of the JS library, so there's no expectation of polish or quality. Trying to use the library is going to involve a learning curve at best and an uphill battle at worst. You are probably going to spend a lot of time looking at source code and comparing Dart classes to their JS equivalents to figure out how anything works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.