Tim_Rosskamp

Create sphere from height map?

Recommended Posts

Hey,

In my project I need to create a sphere with a height map, but I only found the function "CreateGroundFromHeightMap" in the babylonjs docs. It seems like there is not a function for spheres.

Can anybody help me with that? Basicly I need the function "CreateSphereFromHeightMap".

Share this post


Link to post
Share on other sites

@NasimiAsl

Well, I looked at the source code from CreateGroundFromHeightMap and I thought maybe its possible to take the same approach as this function and write a new function that does the same thing for a sphere.

 

But currently this is my code:

import BABYLONX from './plugins/GeometryBuilder.SGB.js';

BABYLONX.GeometryBuilder.InitializeEngine();
BABYLONX.ShaderBuilder.InitializeEngine();

export function createEarthMesh(heightMap) {
    var img = document.createElement('img');
    var canvas = document.createElement('canvas');
    var GB = BABYLONX.GeometryBuilder;

    var CreatePlanet = function(op, GB) {
        var builder = function(s /*{seg:number}*/ , geo){
            var seg = s.seg;
            var hseg = seg;

            var hmap = function(p){
                p = norm(p);
                // read pixel from canvas
                var ns = 53.*canvas.getContext('2d').getImageData( (p.u*200),   ( ((1.-(p.v+0.5))*200)), 1, 1).data[1]/255;

                p.x *=300+ ns;
                p.y *=300+ ns;
                p.z *=300+ ns;
                return p;
            }
            var norm = function(v){
                var x = v.x, y = v.y, z = v.z;
                var n = Math.sqrt(x * x + y * y + z * z);

                if (n == 0) return { x: 0.1, y: 0.1, z: 0.1 };

                var invN = 1 / n;
                v.x *= invN;
                v.y *= invN;
                v.z *= invN;

                return v;
            }
            var def = function(a, d){
                if (a != undefined && a != null) return (d != undefined && d != null ? a : true);
                else
                    if (d != _null)
                        return (d != undefined && d != null ? d : false);
                return null;
            }

            // calculate sphere
            var f = function(i, j, y){
                y = def(y, 0.);
                var a = i * 360. / seg;
                var v = {
                    x: Math.sin((Math.PI / 180.) * a) * 3.,
                    y: j * 2. / seg,
                    z: Math.cos((Math.PI / 180.) * a) * 3.
                };
                var p = {
                    x: v.x * Math.sin(v.y * Math.PI / 2. - Math.PI / 2.),
                    y: Math.sin(v.y * Math.PI / 2.) * 3 + y,
                    z: v.z * Math.sin(v.y * Math.PI / 2. + Math.PI / 2.)
                };
                return p;
            };


            // make sphere points
            for (var i = 0; i < seg + 1; i++) {
                for (var j = -hseg / 2.; j < hseg / 2.; j++) {
                    var p = {
                        x: 0,
                        y: 0,
                        z: 0,
                        u: i / seg,
                        v: j / seg
                    };
                    if (j <= -hseg / 2. + 1.) {
                        p = {
                            x: 0.,
                            y: -3.,
                            z: 0.,
                            u: i / seg,
                            v: j / seg
                        };
                        p = hmap(p);
                    } else if (j >= hseg / 2. - 1.) {
                        p = {
                            x: 0.,
                            y: 3.,
                            z: 0.,
                            u: i / seg,
                            v: j / seg
                        };
                        p = hmap(p);
                    } else {
                        p = f(i * 1.0, j * 1., 0.);
                        p.u = i / seg;
                        p.v = j / seg;
                        p = hmap(p);
                    }

                    // make vertex and uv

                    GB.PushVertex(geo, p);
                    geo.uvs.push(i / seg, (j / seg + 0.5));
                }
            }

            // make face
            for (var j = 1.; j < hseg - 1; j++) {
                for (var i = 1; i < seg + 1; i++) {
                    GB.MakeFace(geo, [(i - 1) * hseg + j, (i - 1) * hseg + j + 1, (i) * hseg + j, (i) * hseg + j + 1], {
                        flip: 0,
                        faceUVMap: "0123"
                    });
                }
            }
        };

        return new BABYLONX.Geometry(GB.GeometryBase(op, builder, op.custom));
    }
    img.onload = function(){
        canvas.width = img.width;
        canvas.height = img.height;
        canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

        var mesh = CreatePlanet({
            seg:200.
	    },GB).toMesh(window.Scene);

        console.log(mesh);
    }
    img.src = heightMap;
}

and this is the error I get:

Uncaught ReferenceError: i is not defined
    at Function.BABYLONX.GeometryBuilder.BuildBabylonMesh (eval at GeometryBuilder.InitializeEngine

Share this post


Link to post
Share on other sites

look line 35

ns = 40.8*cn.getContext('2d').getImageData(
(p.u*200),
( ((1.-(p.v+0.5))*200)), 1, 1).data[1]/255;
 
change 40.8 
and for minimum radius
 
p.x *=300 +ns;
p.y *=300+ ns;
p.z *=300 +ns;
 
change 300 

for add more  segment look line 56  

var mesh = CreatePlanet({
seg:256.
         },GB).toMesh(scene);

Share this post


Link to post
Share on other sites

Great, I fiddled around a bit. Could you please shortly explain what is going on in your code?

So far I think I understood, that you create a 200px x 200px image and scan it pixel by pixel to create a uv map for the height. If I change the image size it will not work anymore.

What exactly is going on there? :)

 

If I try to get the mesh via 

    console.log(scene.getMeshByUniqueID(2));

I only get back NULL.

So there is no chance to export it as OBJ-File.

Share this post


Link to post
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.