• Content count

  • Joined

  • Last visited

  1. Awesome! Thanks so much, Deltakosh.
  2. OK, I made a PG with my flawed unproject implementation. Some notes: 1) If I just position the cube at "worldVector", it is not visible at all. Perhaps because it is too close to the camera? So I make sure the camera looks down the z-axis and move the object to z = 0. I don't want to do this but I think it should work as long as I just size the browser rather than update the camera position. 2) It doesn't matter what coordinates I pick for source. The cube is always positioned in the UL corner. I would think that using: (1, 1, 0) (or perhaps: (engine.getRenderWidth(), engine.getRenderHeight(), 0)) would choose the LR. I would like to choose the viewport-relative position for the mesh. When I change the aspect ratio by sizing the browser, the object doesn't stay fixed against the side of the viewport. Perhaps this is because I'm fixing z? Thanks for taking an interest, I appreciate any help you can give me. - Ken
  3. Hi Deltakosh, I did not read that code. I'll take a look. Also, I'll build a PG for the unproject attempts when I get home tonight (in a few hours). Thanks, - Ken
  4. Hi Again, Let me explain what I'm trying to do first: I want a panel of 3D objects which line up along the left-hand side of the canvas/viewport. I'm trying to create an object factory of sorts. The user will click and drag objects from the object factory into the scene proper, the code will clone the selected object when this occurs. I'm using two scenes for this, one is the main scene, with a ground and control-enabled camera receiving the clones and accumulating state; and another scene, for the factory, that is essentially static but has a camera and lights and meshes (the factory prototypes). As I've said, I want this factory to be arrayed down the left-hand side of the screen. If I choose just any position for the factory objects, they will go into and out of scope when the canvas aspect ratio changes. So I want to be able to calculate a ray which vertically cuts the camera's left-hand viewing-frustum plane, say somewhere in the middle, parallel to the near and far edges. I think this should be a vertical slice, abutting the left edge of the viewport. Here's how I tried to do it: First, I tried using getFrustumPlanes. But the planes it gave me were oddly skewed. When I generated geometric planes for each of the six, for instance, they did not form a convex solid. And even when I mentally tried to figure out which plane was which part of the frustum, I just couldn't make sense of the numbers. I would have expected 2 along each camera-centric axis (e.g. + & - along X, + & - along Y, + and - along Z--I setup a straight-on camera to help in understanding the numbers to no avail). Next, I tried a few of the unproject methods. I think these methods should have converted a 2D point on the screen to a 3D point (or ray) in the world. I read through many posts on this site to use what I thought were the best values for the camera's projection matrix, world matrix (identity), etc.... Never got anything even close to good numbers. Mostly they were NaN until I saw one post which accessed maxima from the engine. But when I positioned my mesh (using a sphere) at the returned 3D vector, it always seemed to go to the same, incorrect place (irrespective of my choice for 2D starting point). Next, I successfully wrote an iterative algorithm which used many of the same transformation matrices along with project. This way, I would choose a 3D point, test where it was in 2D, and knowing the fixed orientation of the camera, choose another 3D point which projected closer to the 2D point for which I was aiming, etc.... Sort of like a newton's method for iteratively approaching the correct value that unproject should give me in fixed time. OK, I can do it, but I want to do it correctly. So my last attempt, for which I have a playground, uses: createPickingRayInCameraSpace. I think this should give me a ray which looks like a point, but really rides the intersection of the left and top viewing-frustum planes (because I choose 0,0). However it does not. Playground demo: Please help. I don't care if I use any of these methods. Is there a better way? Should I be using the aspect ratio directly? Should I just do my own matrix math? Thanks, Ken
  5. That is a really cool idea with the springs. I'm definitely going to play around more wth this stuff. Take care.
  6. Thanks aWeirdo, That does it. I guess its foolish to use physics where a straight forward approach works just fine. Take care, Ken
  7. Thanks for replying,Jerome please notice that my latest demo just sets the rotation quaternion directly. In fact it is hard-coded to "up". Still doesn't work. Thanks for your time, ken
  8. Hi All, I've created another playground example: This time, I'm hard-coding the rotation quaternion to "up", by constructing a quaternion from a rotation axis pointing along the Y-axis with 0 rotation: meshBox.rotationQuaternion = BABYLON.Quaternion.RotationAxis(new BABYLON.Vector3(0, 1, 0), 0); This works in the same way as with Euler angles. That is, it works for a minute then fails to work. I have noticed a slow drift along the X-axis in the negative direction. Once the magnitude of the drift reaches 1/2 the width of the mesh (along the X-axis) the issue starts. Does this make any sense? After all, I am setting the rotation after applying the impulse, thus effectively cancelling the effect for which I'm aiming. Is the imposter becoming disjoint with the mesh somehow? Like the imposter is drifting relative to the mesh? In any case, the oddest aspect is that no matter what I try, the simulation always fails in the same way. Even if I hard-code the orientation! What is going on? Thanks, Ken
  9. Wingnut, Awesome idea. A keel. I love it! Thanks.
  10. fenomas, I'd like to use physics--if for no reason other than the exercise itself. The solution presented with the dampening Euler angles isn't really physics based though. It was just my poor attempt at correcting the problem with the impulses. It made some sort of sense to me that a rounding imbalance in the integration facility of the physics engine could escalate out of control. What doesn't make sense to me is that the dampening would seem to work, then slowly and deliberately stop working (assigning agency to Cannon!) and then start to work again after going haywire for a minute. I don't know enough about quaternions to use them directly--which is why I tried to convert into "intelligible" coordinates. Do you have a reference for quaternions that could help me understand them functionally? I like the idea of using them directly--even if a final solution would be purely physics-based. I appreciate your time, take care, Ken
  11. Hi Wingnut, Thanks for the help, kind words and welcome. Did you see the odd behavior? I'm just not sure what's going on. I noticed something additional since posting the original: the unwanted rotation goes nuts for another minute, then it actually settles down and the whole simulation runs just fine. Do you know if there are some internal accumulators which can be nulled or reset? This really looks like some sort of transient state issue in cannon. I'm just not sure why the adjustment code works, fails to work and then works again. I suppose if I follow your lead, I could continue to apply the impulse to the centroid, and manually apply a non-physics-based rotation to the mesh just for the effect. However, first I want to look into that Y-axis rotation you mentioned. In addition to the "physics engine's rotationDamping feature", it should also produce gyroscopic torque, which should help stabilize the mesh. On the other hand, I tried several different techniques to dampen the errant rotation and it always failed in the same, odd way.... Have a great evening, Ken
  12. Hi! I am new to Babylon.js. Love it so far. I am trying to write a simple game. I want the game character to "float" over the playing field. Right now, I'm just trying to get a simple box to hover. I'm doing it in a somewhat funny way because I want some wobbling to occur as part of the hover. I am trying to use physics. So I have gravity enabled in the scene and collisions enabled for the meshes. Further, I want to apply impulses to the box to get it to hover. I wrote some code to figure out which vertex is the "lowest" of all the verticies of the box. I then apply an impulse to that vertex. Because the vertex is extended from the centroid of the box, a torque is generated by the impulse. I am having difficulty keeping the impulses in range. Typically, without squelching the angular velocity, the box eventually starts rotating out of control. So, I was looking into just manually leveling the rotation using addRotation. First I get the Euler angles from the rotation quaternion. Then I reverse a little bit back onto the box each frame. Oddly, this seems to work very well for about 1 minute. Then suddenly, it fails. I fails slowly, which is even odder to me. It seems like I have to reset some internal state or something.... Can someone point out my missteps? Thanks. Wingnut was kind enough to build a playground example that works (but without the wobble): (see his post below). I also have a running version on my website, at: When I fix the issue, that site will be updated. This snippet shows the original issue. Notice the difference between the working demo Wingnut wrote and this one which doesn't (specifically: the impulses are applied at the verticies here, whereas in the working example, the impulses are applied to the centroid): let dHoverHorizon = 50; let dImpulseForceDivisor = 10; let dRotationAdjustmentFactor = 20; meshBox.registerBeforeRender(() => { try { // Get all the verticies of the mesh, given as an array of 72 floats. // 3 floats for each vertex * // 4 verticies per face * // 6 faces. // // Question #1: Why all 6 faces, which produces 3 times as many verticies as necessary? // Question #2: Is there a way to combine these to remove redundant geometry? let arrayMeshVertexFloats = meshBox.getVertexBuffer(BABYLON.VertexBuffer.PositionKind)._buffer._data; // Extract the 4 verticies for the // face in which we are interested. // This happens to be the 6th face. let arrayMeshVerticies = []; for (let i = 3 * 4 * 5; i < arrayMeshVertexFloats.length; i += 3) { arrayMeshVerticies.push(BABYLON.Vector3.FromArray(arrayMeshVertexFloats, i)); } // Convert these 4 verticies to world coordinates. let arrayWorldVerticies = => { let vertexWorld = BABYLON.Vector3.TransformCoordinates(vertex, meshBox.getWorldMatrix()); // Attach original mesh-vertext to the world-vertex. vertexWorld.localVertex = vertex; // Return the new vertex. return vertexWorld; }); // Just for fun, only allow impulse on the lowest of all verticies. let v3Lowest = null; arrayWorldVerticies.forEach((v3) => { if (!v3Lowest || v3Lowest.y > v3.y) { v3Lowest = v3; } }); // Drop out now, if lowest vertex is above hover-horizon. if (v3Lowest.y > dHoverHorizon) { return; } // Generate an impulse proportional to a square- // root of the drop down from the hover-horizon. let dImpulseForce = Math.sqrt(dHoverHorizon - v3Lowest.y) / dImpulseForceDivisor; // Get the linear velocity. let v3LinearVelocity = meshBox.physicsImpostor.getLinearVelocity(); // Only care about the y-axis. let dLinearVelocityAlongYAxis = v3LinearVelocity.y; // If the velocity is negative, then increase the impulse. // Eventually, this will need to take mass into consideration.... if (dLinearVelocityAlongYAxis < 0) { dImpulseForce *= (1 - dLinearVelocityAlongYAxis); } // This doesn't seem to work in a madening way: // Actually, it works for about 1 minute, then // just slowly and seemingly-deliberately fails. let v3Rotation = meshBox.rotationQuaternion.toEulerAngles("XYZ"); meshBox.addRotation(-v3Rotation.x / dRotationAdjustmentFactor, -v3Rotation.y / dRotationAdjustmentFactor, -v3Rotation.z / dRotationAdjustmentFactor); // Apply an "up" impulse to the physics // imposter at the local location of the // lowest vertex found during this pass. meshBox.physicsImpostor.applyImpulse(new BABYLON.Vector3(0, dImpulseForce, 0), v3Lowest.localVertex); } catch (e) { console.log("Error in meshBox.registerBeforeRender: " + e.message); } });