Jump to content

Convert updateMeshPositions to Global


Pryme8
 Share

Recommended Posts

I am currently manipulating a series of ground objects.  I am able to manipulate the ground with different noise effects and calculations to get the effects I am desiring on a single ground plane.  The problem when I am doing it with the series of them they are all effectively getting the same manipulation applied. 

I am generating the ground objects in a block so they are all one right after another and look like a single plane, so they all have an offset in the global space.  How then can I convert the point from its local assignment in the script:

TERIABLE.UpdatePositions = function (positions) {			
    for (var idx = 0; idx < positions.length; idx += 3) {
        positions[idx+1] = positions[idx]*positions[idx+2];
    }
};


//Section where it is called:

this._block.updateMeshPositions(TERIABLE.UpdatePositions);

to a global position.  I might be able to do it by adding the grounds.position.x and y to the idx values? but I have not tried that yet and I am not even sure how to pass the ground object with the positions on the updateMeshPositions call

i see no optional variable offset in http://doc.babylonjs.com/classes/2.3/Mesh

 

Link to comment
Share on other sites

Well, you've got two solutions as, like you justly said, the function updateMeshPosition() only knows the parameter positions :

1 - the code of this function is quite light : https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.mesh.ts

Thus you might re-implement your own function from this pattern and then add your parameter offset.

2 - else, you could also just do with the javascript capabilities :

var currentOffset = 0;       // this variable value will be enclosed in the function
TERIABLE.UpdatePositions = function (positions) {			
    for (var idx = 0; idx < positions.length; idx += 3) {
        positions[idx+1] = positions[idx]*positions[idx+2] + currentOffset; // use it anywhere in the function
    }
};


//Section where it is called:
currentOffset = this._block.offset;  // set the offset value to the current block one's
this._block.updateMeshPositions(TERIABLE.UpdatePositions);

This should work easily

Link to comment
Share on other sites

I solved it with using VertexData, now I have a new problem that maybe you can help me with.

Here is the new Update position function, I did away with original one and did my own so I could pass the information I wanted.  Using this function with updateVerticesData gives me the ability to manipulate the position of the mesh the way I want, the problem now is as this operation is called a second time with different parameters it seems to only reference the blocks original state vertex data not the new positions.

This could be because I am storing the block in an Object TERIABLE.Region = [], where the block in the update function is a reference to the TERIABLE.Region[count] of the calling function.

I figured information in TERIABLE.Region[count] were direct references seeing how I can use them to manipulate the object I want... but it seems like if more then one VertexData is applied in a stacked order ie the first one is processed and applied before the second is added to the stack.  Its not ASNYC i have it procedural for the calling of these functions.

TERIABLE.UpdatePositions = function (block, state, activeItem) {
    //PERLIN 2D
    if(state =="Perlin2D"){console.log("Perlin2D applyed");
        var xDiv = $(activeItem).children("#perlin-2d-x-divider").val();
        var yDiv = $(activeItem).children("#perlin-2d-y-divider").val();
        var height = $(activeItem).children("#perlin-2d-height").val();
	var seed = $(activeItem).children("#perlin-2d-seed").val();
				
	noise.seed(seed);
							
	var vertexData = block.getVerticesData(BABYLON.VertexBuffer.PositionKind);
				
	for (var i = 0; i < vertexData.length; i += 3) {
		var x = vertexData+block.position.x, z = vertexData[i+2]+block.position.z;
		vertexData[i+1] = (noise.perlin2(x/xDiv, z/yDiv)*height);
	}
					
	block.updateVerticesData(BABYLON.VertexBuffer.PositionKind, vertexData, 0, 0);
			}
			
     if(state == "Clamp"){console.log("Clamp applyed");
	var clampUp = $(activeItem).children("#clamp-upper").val();
	var clampLow = $(activeItem).children("#clamp-lower").val();
				
	var vertexData = block.getVerticesData(BABYLON.VertexBuffer.PositionKind);
				
	for (var i = 0; i < vertexData.length; i += 3) {
	    var y = vertexData[i+1];
	    if(y>clampUp){
		vertexData[i+1] = clampUp;
            }
	    if(y<clampLow){
		vertexData[i+1] = clampLow;
	    }
					}
	block.updateVerticesData(BABYLON.VertexBuffer.PositionKind, vertexData, 0, 0);
	}
			
};

The Second part of this question would be how now, can I update the normal data,  I know the normal's will change because of the shift in positions of the vertices and it would not be as simple as apply the same Noise to the values (or would it)  because they do not represent a XYZ but rather a Angular Vector...  is there some sort of built in function to call an update to the Normal Data dependent on the positions of the vertices?

I attached screenshots so you can kinda get and Idea of whats going on, this is with only one noise applied and different values blah blah... anyways the "blocks" are colored random for visibility right now as I develop.  The Blocks compose a region, a region is a basic styling of a land mass...  Eventually your going to be able to design your procedural generated landscapes in TERIABLE and then export them as called objects that will have LOD and infinate expansion.
The next step is to make it so that when you apply Noise layers to make it an absolute reference or a additive/subtractive one.  Then add masks and procedural texturing support.  Lucky I have already developed a html5 canvas paint program that is pretty robust so I will implement that in as well to allow live painting of reference textures and direct manipulation layers that you can assign to different blocks or areas of regions.

Anyways thats why I have all these questions,  If you could help me figure out the normals thing and the stacking of the Vertex Data manipulations Ill totally stick you in the credits.

TERIABLE_ALPHA_2_SS1.jpg

TERIABLE_ALPHA_2_SS2.jpg

TERIABLE_ALPHA_2_SS3.jpg

TERIABLE_ALPHA_2_SS4.jpg

UPDATE***

I figured out the clamping I had a logic error... dumb dumb... I bet its the same reason the new noise layers dont seem to apply to the updated mesh, ill do more research and then update!

 

if(state == "Clamp"){
	console.log("Clamp applyed");
	var clampUp = $(activeItem).children("#clamp-upper").val();
	var clampLow = $(activeItem).children("#clamp-lower").val();
	var vertexData = block.getVerticesData(BABYLON.VertexBuffer.PositionKind);
	
        for (var i = 0; i < vertexData.length; i += 3) {
	        var y = vertexData[i+1]+block.position.y;
		if( y > clampUp || y < clampLow){
			if(y > clampUp){y = clampUp}
				if(y < clampLow){y = clampLow}
					vertexData[i+1] = y;
				}
			}
		block.updateVerticesData(BABYLON.VertexBuffer.PositionKind, vertexData, 0, 0);
		return;
                }
         }

};

*** UPDATE 2

Fixed it all.. I'm a dumbbell...  I was setting the values on the Perlin2d as absolute... and my min max still was flawed I should have seen that I dont know why I did it with if statements in the first place...

 

TERIABLE.UpdatePositions = function (block, state, activeItem, count) {
			console.log(block.name);
			//PERLIN 2D
			if(state =="Perlin2D"){
				console.log("Perlin2D applyed");
				
				var xDiv = $(activeItem).children("#perlin-2d-x-divider").val();
				var yDiv = $(activeItem).children("#perlin-2d-y-divider").val();
				var height = $(activeItem).children("#perlin-2d-height").val();
				var seed = $(activeItem).children("#perlin-2d-seed").val();
				var mode = $(activeItem).children("#perlin-2d-mode").val();
				
				noise.seed(seed);
							
				var vertexData = block.getVerticesData(BABYLON.VertexBuffer.PositionKind);
				
					for (var i = 0; i < vertexData.length; i += 3) {
						var x = vertexData+block.position.x, y = vertexData[i+1]+block.position.y ,z = vertexData[i+2]+block.position.z;
						vertexData[i+1] = (noise.perlin2(x/xDiv, z/yDiv)*height);
						switch (mode){
							case "Additive":
								vertexData[i+1] += y;
								break;
							case "Subtractive":
								vertexData[i+1] -= y;
								break;		
						}
					}
					
				block.updateVerticesData(BABYLON.VertexBuffer.PositionKind, vertexData, 0, 0);
				return;
			}
			
			if(state == "Clamp"){
				console.log("Clamp applyed");
				var clampUp = $(activeItem).children("#clamp-upper").val();
				var clampLow = $(activeItem).children("#clamp-lower").val();
				
				var vertexData = block.getVerticesData(BABYLON.VertexBuffer.PositionKind);
				
				for (var i = 0; i < vertexData.length; i += 3) {
						var y = vertexData[i+1];
						vertexData[i+1] = Math.min(Math.max(y, clampLow), clampUp);
					}
				block.updateVerticesData(BABYLON.VertexBuffer.PositionKind, vertexData, 0, 0);
				return;
			}
			
		};

 

TERIABLE_ALPHA_2_SS5.jpg

Edited by Pryme8
Update Agian
Link to comment
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...