Raggar Posted September 2, 2016 Share Posted September 2, 2016 I need some simple pointers on how to turn an imported model into a Cannon.js heightfield. I would prefer this over actual heightmaps, as I feel that I'm more in control of the design of the ground. I made a simple PG example so I can test it along the way. Just a very basic model made out of a 20x20 plane. How would you pull the positions(Especially Y) on the individual vertices, so they can be used to create the heightfield shape and added to a Cannon.js body? This is the relevant code from the heightfield demo: var matrix = []; var sizeX = 15, sizeY = 15; for (var i = 0; i < sizeX; i++) { matrix.push([]); for (var j = 0; j < sizeY; j++) { var height = Math.cos(i/sizeX * Math.PI * 2)*Math.cos(j/sizeY * Math.PI * 2) + 2; if(i===0 || i === sizeX-1 || j===0 || j === sizeY-1) height = 3; matrix[i].push(height); } } https://github.com/schteppe/cannon.js/blob/master/demos/heightfield.html Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted September 2, 2016 Share Posted September 2, 2016 If you can wait like a week I'll post my solution that I've been cooking up for terrain everything. Search the forum for TERIABLE until I release the new version though for some solutions to your questions. Quote Link to comment Share on other sites More sharing options...
Raggar Posted September 4, 2016 Author Share Posted September 4, 2016 Well. I am not making any progress, that's for sure. I'm trying to find out how the DiStraction demo does it: http://www.babylonjs.com/Demos/Distraction/ I'm using the very same mesh, with most of the stuff stripped off. But for some reason, when I try in the playground, the verticies are all aligned flat, and the sphere just falls through where the heightfield is supposed to be: http://www.babylonjs-playground.com/#PTXTK#7 If you comment out o.dispose() on line 133, you'll see the shope of the original imported mesh Here is the original, unminified code, if that would help anyone make sence of this: Ground.prototype._createGround = function() { this.msgCallback && this.msgCallback("create ground..."); var e = this; BABYLON.SceneLoader.ImportMesh("", this.groundPath, this.groundMesh, this.scene, function(t) { var i, s; for (i = 0; i < t.length; i++) { var o = t[i]; if (-1 !== o.name.indexOf("Water") && (o.receiveShadows = !0), -1 !== o.name.indexOf("Support") && (o.receiveShadows = !0), null !== o.getVerticesData(BABYLON.VertexBuffer.PositionKind)) if (o.name === e.groundMeshName) { e.ground = new BABYLON.GroundMesh("", e.scene), e.ground._setReady(!1), e.ground._subdivisions = e.subdivision; var a = BABYLON.VertexData.CreateGround(e.width, e.depth, e.subdivision); if (null !== e.groundTexture) { var n = new BABYLON.StandardMaterial("", e.scene); n.alpha = 1; n.diffuseTexture = new BABYLON.Texture(e.groundTexture, e.scene), n.backFaceCulling = !0, e.ground.material = n } var r = a.positions, d = o.getVerticesData(BABYLON.VertexBuffer.PositionKind), h = d.length / 3, l = e.width / e.scaleFactor; for (s = 0; h > s; s++) { var c = d[3 * s] * o.scaling.x, p = d[3 * s + 1] * o.scaling.y, u = d[3 * s + 2] * o.scaling.z, g = Math.round((c + l / 2) * e.subdivision / l), f = Math.round((u + l / 2) * e.subdivision / l), m = g, w = e.subdivision - f, B = m + (e.subdivision + 1) * w; r[3 * B + 1] = p * e.scaleFactor + 50 } var C = a.normals, y = a.indices; BABYLON.VertexData.ComputeNormals(r, y, C), a.applyToMesh(e.ground, !1), e.ground._setReady(!0), o.dispose(), e.ground.receiveShadows = !0, e._createCannonHeightfield() } else e._moveAndScaleMesh(o), o.convertToFlatShadedMesh(); else e._testEmptyMesh(o) } }) } Ground.prototype._createCannonHeightfield = function() { var t, a, n, s = this.ground.getVerticesData(BABYLON.VertexBuffer.PositionKind), o = []; for (a = 0; a <= this.subdivision; a++) for (o.push([]), n = 0; n <= this.subdivision; n++) { var r = a + (this.subdivision + 1) * (this.subdivision - n); t = s[3 * r + 1], o[a].push(t) } var d = new CANNON.Heightfield(o, { elementSize: this.width / this.subdivision }); this.groundBody = new CANNON.Body({ mass: 0, material: this.groundMaterial }); this.groundBody.addShape(d); this.groundBody.position.set(-this.width / 2, -this.depth / 2, 0); this.groundBody.collisionFilterGroup = this.groundCollisionFilterGroup; this.groundBody.collisionFilterMask = this.groundCollisionFilterMask; this.world.add(this.groundBody); // this._loadSolidBuildings(); this._loadSolidBox(); if (this.onLoadFinished) { this.onLoadFinished(); } }; Ground.prototype._testEmptyMesh = function(e) { var t, i = !1; for (t = 0; t < this.scene.meshes.length; t++) { var s = this.scene.meshes[t]; if (s.parent === e) { i = !0; break } } i ? e.setEnabled(true) : e.dispose() }; Quote Link to comment Share on other sites More sharing options...
RaananW Posted September 5, 2016 Share Posted September 5, 2016 Hey, why work hard, when everything is already implemented? http://www.babylonjs-playground.com/#1GQK6J You just need to be conform with a babylon heightmap, and you are fine. This is whyt I removed the parent (which indicates compound physics bodies), and baked the transformation into the heightmap. Pryme8, Wingnut and Raggar 3 Quote Link to comment Share on other sites More sharing options...
Raggar Posted September 6, 2016 Author Share Posted September 6, 2016 Well, that would certainly work client-side. But when it comes to running the same simulations server-side, using only Cannon.js, and not Babylon.js, this simply won't work. I'm planning on using the array of vertex positions to recreate the heightfield server-side, but as testing blindy isn't quite as easy as having some visuals, I'll see if I can make it work using Babylon.js first. This is what I got so far: http://www.babylonjs-playground.com/#1B5UCR#3 Using the VertexData tutorial from pixelcodr: http://pixelcodr.com/tutos/trees/trees.html As you can see, the randomization of the vertices is successful, but when I try to apply the vertex information from the imported mesh into the created ground mesh, it simply gets all messed up. If you check the console, you see that the getVerticesData function ran against the created ground mesh results in an array of 288, where as the same function ran against the imported mesh results in 75. Why is this? The ground consists of a 4x4 grid, and the model is made using a 4x4 grid aswell. Shouldn't they have the same number of vertices? Now I think about it, the 3Ds Max model might have been made out of rectangles instead of triangles. Hmm. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted September 6, 2016 Share Posted September 6, 2016 why does everyone want to do all their hit testing server side? This is not the way to do it, yes you want to do secondary calculations on the server but the majority of the i/O's need to be calculated on the client then pushed to the sever to confirm that it was valid and if they are out of a normal range push them back in. Quote Link to comment Share on other sites More sharing options...
Raggar Posted September 6, 2016 Author Share Posted September 6, 2016 I can't speak for anyone else, but this is the way I have chosen to approach it Edit: Making a triangular mesh creates the same amount of vertices, so that's not where the problem lies. Another thing, if I change lines 44 and 45 to: var positions2 = ground.getVerticesData(BABYLON.VertexBuffer.PositionKind); var positions = newMeshes[1].getVerticesData(BABYLON.VertexBuffer.PositionKind); In order to get the positional data on the vertices of the imported model, I get a double: TypeError: i is undefined | babylon.js:6:14936. Quote Link to comment Share on other sites More sharing options...
RaananW Posted September 7, 2016 Share Posted September 7, 2016 A quick question - why can't you take the code from babylon and use it server-side? Quote Link to comment Share on other sites More sharing options...
Raggar Posted September 9, 2016 Author Share Posted September 9, 2016 @hen suggested the same thing, but I haven't had much time lately. I'll see if I can make it work later tonight, as I did one quick test. This test was almost a success, as it worked with a mesh created with babylon, but not a model imported on my own. I might have missed something, though. Quote Link to comment Share on other sites More sharing options...
Raggar Posted September 13, 2016 Author Share Posted September 13, 2016 I see that I forgot to reply. @RaananW's suggestion worked like a charm, and copying the matrix to the server-side only took a matter of minutes with some organized logging. As the server and the client run the same simulations, they seem to sync up pretty well, but player prediction in mind. But prediction, compensation and reconciliation aren't quite easy tasks. It really puts multiplayer in a whole new perspective. RaananW 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.