Q3D V-2.4 [3D Physics + Skeletal Animation UPDATE]

  • Hi, it's been a while. To anyone who knows the answer to this question (I've searched). But to setup the context, lets say we have an .obj with three cubes.

    I see the "SYSTEM --> For Each child" and upon iteration, the .idPicked property shows unique numbers. Great.

    But applying something like "Q3DMaster --> Set object visible" to false doesn't seem to have any effect.

    QUESTION:

    Does the "System --> For Each child" work for loaded .obj that has children (the three cubes in this case) at all?

    Or is it only useable for Q3DModels instantiated/created in C2?

    WHY:

    ThreeJS's Object3D.traverse(callback) seems to fit the bill for this type of useage. Just asking

    https://threejs.org/docs/#api/core/Object3D

    Super interesting question! One of the limitations I have been living with is a low object count. If I try to do lots of objects, I quickly overload the CPU. Being able to do instances of objects like you can in Babylon3d would be great. QuaziGNRLnose, is this possible with Q3D?

  • Being able to do instances of objects...

    I've just tested with ThreeJS/JavaScript and it is possible to do so -- absolutely.

    In fact, the name of the mesh (obj's 'o' key) is retained, where, you can access it by the child's .name property. From there you can then translate, rotate, scale etc...

    The caveat in going that route is, of course, the missing "IDE" but other than that, the plumbing work in ThreeJS is already there.

    EDIT:

    Just noticed that .PickChildren is also available for Q3DModel plugin (that loaded .obj files) but doesn't expose the .name property. Why?!

    EDIT 2:

    I see why. The OBJLoader.js included in Q3D is actually a different implementation than Three.js and only accounts for vertices, normals, uvs and disregards the rest [strike](including object names).[/strike] Perhaps this was done to allow certain use cases in the C2 editor that, over time, was never meant to be.

    EDIT 3:

    Oops. Not true, the object name supposedly looks like it is saved... Now curious as to why it isn't available.

    EDIT 4:

    Aha... it's because it was a design decision. Okay, question answered.

    cjbruce

    I don't think we'll ever get that feature in the current Q3D -- despite it being perfectly doable in actual ThreeJS + JavaScript. That is, unless some major work is done to the OBJLoader (and some other implementation files).

    *sigh* what a downer.

  • > Being able to do instances of objects...

    >

    I've just tested with ThreeJS/JavaScript and it is possible to do so -- absolutely.

    In fact, the name of the mesh (obj's 'o' key) is retained, where, you can access it by the child's .name property. From there you can then translate, rotate, scale etc...

    The caveat in going that route is, of course, the missing "IDE" but other than that, the plumbing work in ThreeJS is already there.

    EDIT:

    Just noticed that .PickChildren is also available for Q3DModel plugin (that loaded .obj files) but doesn't expose the .name property. Why?!

    EDIT 2:

    I see why. The OBJLoader.js included in Q3D is actually a different implementation than Three.js and only accounts for vertices, normals, uvs and disregards the rest (including grouping names). Perhaps this was done to allow certain use cases in the C2 editor that, over time, was never meant to be.

    cjbruce

    I don't think we'll ever get that feature in the current Q3D -- despite it being perfectly doable in actual ThreeJS + JavaScript. That is, unless some major work is done to the OBJLoader (and some other implementation files).

    *sigh* what a downer.

    Thank you for looking into this! I agree with the design decision. Given the choice between using C2 style picking that just works in Q3D, and the confusion that arises with "meshArray" in B3D, I would go with the simpler-to-understand Q3D approach as well.

  • I'm having some probems with Z sorting 3D files in Q3D. Even if I palace things on different layers they seem to have Z errors. Thought that the order creation would place them on top but no luck. Any ideas? Or am I missing something here. Tried Scirra z order, and Q2D sort order but they still display wrong.

    Cheers,

    http://www.liquid-glass.com/123/test.capx

    I'm sorry to take so long to look at the .capx. I was out on vacation, and just got back today.

    I noticed a few odd things:

    1. You are creating 4 new objects every tick in the "MATRIX" event sheet. This makes it almost impossible to debug anything because it quickly drops the frame rate to a standstill. I put all four object creation events under a single "On Start of Layout" so that you only create them once.

    2. You are placing each object in an unexpected way. They all have almost, but not quite, the same z position:

    (500,500,1)

    (500,540,2)

    (500,580,3)

    (500,620,4)

    Given that each box is a 50 x 50 x 50 cube, did you really mean to space them 1 apart in the z-direction?

    3. You don't need to create a new object type each time you want to place an object. I assume each of these should be an instance of the "crate" object, or something similar? If you want 4 of them, just use a for loop to create one and place it appropriately each loop. Or just drag them out onto the layout by hand. I place everything in my level using a top-down view, then position the camera so it looks at everything from a 60 degree angle.

    If you are interested, I can send you a sample .capx showing how I would place things in the layout, then design the 2D UI on top of that.

    Have you given any thought to how you want to design x-y coordinates? Do you want to place everything on a standard x-y grid, then move the camera so it is looking from an isometric perspective? Or do you want to place everything in an isometric grid to begin with? I haven't done an isometric game before, so I'm not sure how people typically lay things out. I suppose it primarily affects the mathematics of character movement...

  • fuego

    Q3D Wasn't really designed with nested objects in .obj's in mind, Since this doesn't really fit with the workflow of Construct's picking system. Really you should have one Q3DModel for every static geometry. There's kind of no point working without constructs picking inside construct, and the advantage of using Q3D+C2 over javascript alone quickly disappears with lots of added overhead. Some Q3D things are redesigned from three.js to give speedup / avoid bad practices that would quickly ruin performance. I

    cjbruce

    What do you mean by instancing?

  • cjbruce

    What do you mean by instancing?

    "instances" is a term used in babylonJS to describe identical 3D objects added to an array and rendered in a single draw call. I have been struggling with adding more than a handful of projectiles onscreen before frame rate drops, and was hoping that I was missing something in the way I was creating and handling the objects.

    I'm also a little worried because I haven't really started populating levels with anything more than blocks. I assume that the best practice is to import the entire level as one big 3D model, correct?

    One more question: I have created toy robots that consist of a body, 2 motors, and 2 wheels. The motors and whels are positioned on the body, and their rotation is controlled programmatically by torque applied to the wheels. I am setting the position of each wheel and motor in world coordinates, because I can't seem to correctly parent the rotating objects to the robot body and spin them in terms of local coordinates. Am I missing something here? I should be able to do this, shouldn't I? Setting position and rotation of all of the wherls and motors every tick is taking up a significant chunk of CPU time, and I need to figure out how to do things more efficiently.

  • cjbruce

    The issue seems to be with the use of physics more than with the rendering of objects. A scene without physics should take many many objects before it slows on any okay CPU.

    It's probably a better idea to fake the movement by considering the entire car a single rigidbody and applying torques to that to emulate wheels. Using hinges on cylinders will lead to trouble getting a good contact patch and make the controls poor, as well as open up the possibility of wheels getting out of alignment. This will also be much less costly

  • QuaziGNRLnose

    I hear you. And understand where you're coming from.

    Just know that, nobody buys a sports car that is speed-limited because the manufacturer knows it's dangerous for you. It has always been up to the content author / developer to avoid bad practices that would ruin game performance. Just my two cents.

    Still, I appreciate the coding efforts and the choices (sacrifices) that were made to make it work as solidly as it does today. Would have loved to hear some of your development anectdotes.

  • cjbruce

    The issue seems to be with the use of physics more than with the rendering of objects. A scene without physics should take many many objects before it slows on any okay CPU.

    It's probably a better idea to fake the movement by considering the entire car a single rigidbody and applying torques to that to emulate wheels. Using hinges on cylinders will lead to trouble getting a good contact patch and make the controls poor, as well as open up the possibility of wheels getting out of alignment. This will also be much less costly

    Actually, what I wrote above isn't exactly true. I am using a separate set of 4 invisible cylinders for the physics movement, and just setting the rotation of the visible wheels and motors based on the angular velocity of the invisible drive wheels. I really like the way the robots drive, and it gives the game a good feel when you land on a ramp or hit the ground:

    https://dl.dropboxusercontent.com/u/55106174/rrfpsbattlearenatest/index.html

    Press "2" to switch from the electric tank to the laser tank to see a closeup of the motors and drive wheels.

    My problem is that 4 of the "laser tanks" require 6% of the CPU time in the debugger just to handle the position and rotation of the wheel and motor "eye candy". I would like to put visual wheels and motors on the other robots as well, but I will quickly overload the CPU if I try to do this. I feel like I should be able to save some CPU cycles by parenting the wheels to the body and positioning/rotating them locally, rather than in world coordinates. I just can't seem to get this to work correctly.

    Edit: You can see the "invisible wheels" on the electric tank. The laser tank uses these as well, but they are invisible for the laser tank. We aren't done with the 3D models for the electric tank yet, so the current model is just a stand-in.

  • cjbruce

    I suggest doing away with the physics based wheels entirely, and making the cars spheres/blocks instead. This should significantly boost performance and is how most video-game cars are implemented. Im assuming you made the wheels invisible because they were acting strangely? I realize this is probably a big change to make but my experience tells me its the best way to go.

  • cjbruce

    I suggest doing away with the physics based wheels entirely, and making the cars spheres/blocks instead. This should significantly boost performance and is how most video-game cars are implemented. Im assuming you made the wheels invisible because they were acting strangely? I realize this is probably a big change to make but my experience tells me its the best way to go.

    The physics-based wheels are acting great, and aren't the CPU hogs that I am referring to. The reason I want to keep them and not show them is they provide for a nice movement feel and automatically take care of orienting the players properly when going over rough terrain or when driving up on top of other players. I tried a raycasting solution earlier, but it was a little wonky and never looked quite right. In the end, you might be right--it will make for a much simpler game to remove the wheel-based movement, but I would like to try to keep them for now.

    The CPU hog I am referring to has to do with positioning/rotation of the visual elements. I should be able to parent them to the body and do rotation about a local axis, shouldn't I?

    Edit: Here is a screenshot showing the offending events:

  • cjbruce I say keep the wheels, create a new vehicle version and write a function to switch between the two. First reason is for performance (if slow), the other is for different vehicle-looks after consuming power-ups if the game has such an intention. A little bit of product differentiation goes a long way.

    ... has to do with positioning/rotation of the visual elements. I should be able to parent them to the body and do rotation about a local axis, shouldn't I?

    Gosh. Imagine designing a wide variety of vehicles like this as opposed to having a 3D modeller design and rig it, you use a single Object3D and have it's children transformable whenever needed. The division of labor is also clear cut.

    But I digress, parenting not working for you?

    BTW. Nice game!

  • Gosh. Imagine designing a wide variety of vehicles like this as opposed to having a 3D modeller design and rig it, you use a single Object3D and have it's children transformable whenever needed. The division of labor is also clear cut.

    But I digress, parenting not working for you?

    BTW. Nice game!

    Thanks for the encouragement! I'm hoping it turns out well so that more people see html5 as a viable alternative for 3D.

    I will definitely take a look at parenting again. It should work, its just that each time I tried, it came out wonky.

    I realized after the first version of Robot Rumble, people weren't as interested because I tried to do all of the artwork myself. This time I have a professional 3D artist on the project, and I'm really excited to see how it goes!

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Solved it! The problem with parenting and setting transform = Yes is that I had initially scaled the laser body model in x,y, and z. This meant that the motors were also scaled in x,y,z and came out elliptical instead of round. All I had to do was to scale each motor/wheel by the same amount whenever I created them. The correct order of operations is:

    1. Create a "laserwheel".

    2. Set it to the correct position on the laserbody.

    3. Change the laserwheel's parent to "laserbody", with Transform:Yes.

    4. Set the laserwheel's local object scale to the same ratio of Sx, Sy, and Sz as the laserbody. In this case, (self.Sx*1, self.Sy*0.6, self.Sz*0.7).

    Now that everything is parented correctly, it takes a single event running each tick to correctly rotate each wheel and motor about its local y axis. This cut the CPU usage for these events by 80%.

  • cjbruce

    Parenting should work fine, you just have to be careful with the transformations because it gets complicated! There's no need to manually shift things like that and it is quite expensive. I see you've fixed it already though

Jump to:
Active Users
There are 2 visitors browsing this topic (0 users and 2 guests)