can't convert from local to worldspace.

In my game, I’m trying to make a space/time field that expands based on what objects are flying through it. It’s top down, so the field is hypothetically 2d, (it’s still in 3d space, but we’ll forget that for now.) ivkoni helped me extensively when creating this script.

here is my script so far…

var player: GameObject;
var objects = new Array();
var initGridVerts : Vector3[];

function extrudeGrid (x, z, r, amp, exponent) {

	
	var gridMesh : Mesh = gameObject.GetComponent (MeshFilter).mesh;
	var gridVerts = gridMesh.vertices;
	var tar : Vector3;
	var dx : float;
	var dz : float;
	var dist : float;
	var nrmlDist : float;
	var nrmlDist2 : float;
	var rot : float;
	
	//run through a list of all vertices, check their distances

	

	for (var i=0;i<gridVerts.length;i++) {
		
		tar=gridVerts[i];
		
		dx = tar.x - x;
		dz = tar.z - z;
		dist = Mathf.Sqrt(dx * dx + dz * dz);
		

		
		if (dist <= r) {

			nrmlDist = 1-dist/r;
			nrmlDist2 = Mathf.Pow (nrmlDist, exponent);
			rot = Mathf.Atan2 (dz, dx);
			tar.x += Mathf.Cos (rot) * nrmlDist2 * 2;
			tar.z += Mathf.Sin (rot) * nrmlDist2 * 2;
			


		
		} 
		
		gridVerts[i]=tar;
		
	
		
	}

	gridMesh.vertices = gridVerts;
	gridMesh.RecalculateNormals();
	gridMesh.RecalculateBounds();



}


function gridReset () {
	
	var gridMesh : Mesh = gameObject.GetComponent (MeshFilter).mesh;
	var gridVerts = gridMesh.vertices;

	
	for (var i=0;i<gridVerts.length;i++) {


		gridVerts[i]=initGridVerts[i];

	}


	gridMesh.vertices = gridVerts;
	gridMesh.RecalculateNormals();
	gridMesh.RecalculateBounds();


}

function Awake () {
	
	var gridMesh : Mesh = gameObject.GetComponent (MeshFilter).mesh;
	initGridVerts = gridMesh.vertices;

	objects.Push (player);

}	


function Update () {
	

	
	for (i=0; i<objects.length; i++) {
	
		tar = objects[i];
		extrudeGrid (tar.transform.position.x, tar.transform.position.z, 20, 10, 1);	
	
	
	}
	
	
}

right now the player object is the only thing traveling through space. However, here’s what happens when I have multiple grids…

as you can see, two of the other graphs which are not at the origin of the world are expressing the same information as the correct graph at the origin, the one with the player ship over it.

I think this is because tar, the variable which is used to calculate where the space time field should be moved, is expressed in worldspace and not local space. Any ideas on how to fix this? I can’t use a large grid for the whole thing, because the for loop would have to run through too many vertices for this to be feasible. Thanks for any and all help.

Sam

Hmmm… this looks like an instatiation and shared mesh problem.

When creating your mesh, how are you positioning it? Do you just drag some into the scene and stitch them together?

The best solution for this is to create a grid manager. This will draw each grid and could possibly only draw the 4 points needed if nothing affects it.

To do this you will need a single controller object, that creates as many grids as you need, (noting the planet does not have a grid, it may have to control what is in each spot)

OK, each grid can be as few as 4 points and as many as 400. What determines that is a list of objects that can be shown in space. If any object is within R of the bounds of the grid, draw the grid, if not, then only draw 4 points.

Each grid is based off of a single “square” texture tiled 20 times over. Each UV on the grid is ranged from 0 to 1 within the grid. (20 slices=1/20th of a uv point.

OK, the best way to do this is to create the vertices, UV’s and triangles on the fly each frame, you can at the same time set up the bubble charge, so that you are not iterating through the grid more than once.

I know its alot, give it a try and lets see what you come up with.

yes, I am just stitching them together, It’s a plane I pre-made in maya. Can you provide a little more depth on how to accomplish this manager technique?

for the variable ‘tar’ instead of :

	var rot : float;
	
	//run through a list of all vertices, check their distances

	

	for (var i=0;i<gridVerts.length;i++) {
		tar = gridVerts[i];
                .......
		gridVerts[i]=tar;
                .......
         }

do

	var rot : float;
        var local2World : Matrix4x4 = transform.localToWorldMatrix;
        var world2Local : Matrix4x4 = transform.worldToLocalMatrix;
	
	//run through a list of all vertices, check their distances

	

	for (var i=0;i<gridVerts.length;i++) {
		tar = local2World.MultiplyPoint3x4( gridVerts[i] );
                .......
		gridVerts[i]= world2Local.MultiplyPoint3x4( tar );
                .......
         }

thanks for all the help guys. I went ahead and tried both ideas. BDev’s idea works fine, but I would still like a way to keep track of them with a grid manager. So I tried my hand at writing a script, and while it doesn’t work fully i’d like you guys to be able to see if I’m doing this right.

What I have so far…

 var gridArray : GameObject[];
var gridPiece : GameObject;
var drawDistX : float;
var drawDistZ : float;
var drawOrigin : Vector3;




function drawGrid (gridPiece : GameObject) {
	
	var instHere : Vector3;
	var posX : float;
	var posZ : float;
	var posY : float; //Don't mess with posY
	
	for (i=0;i<gridArray.length;i++){
		
	
		
		while (gridArray[i].transform.position.x < drawDistX || gridArray[i].transform.position.z < drawDistZ){
			
			posX++; 
			posZ++;
	
			instHere = Vector3 (posX, posY, posZ);
			
			gridArray+=[gridPiece];
			
			Instantiate (gridArray[i], instHere, transform.rotation);
			
		}
		
			if (gridArray[i].transform.position.x > drawDistX || gridArray[i].transform.position.z > drawDistZ) {
				
				gridArray[i] = gridArray[1];	
				Destroy (gridArray[1]);
	
	
	
		}
	}	
}

basically, it instantiates a bunch of squares that have my grid expansion script on them within a certain range specified by distX and distZ. if it’s out of that range, it set its value in the array to 1 and then destroys 1.

Should this work?

p.s. sorry for the messy code… i don’t don’t know how to use indentations on the forum

I think that is a lot of maintenance. I don’t even think you really need to have a fixed grid. Try someting like this ( i’m going to write it in C# because i don’t know js very well )

[RequireComponent(typeof(MeshFilter)]
public class LevelGrid : MonoBehavior
{
    public int rows = 10, columns = 10;
    public Vector2 cellSize;
    public float z = 0;
    Vector3[] vertices;
    Mesh mesh;
    void Start() {
        if( rows <= 0 || colums <= 0 ) throw new System.ArgumentException("Invalid dimensions");

        int vertexCount =  ( rows + 1 ) * ( columns + 1 ) ;
        vertices = new Vector3[];
        Vector2[] textureCoords = new Vector2[ 
        int[] triangles = new int[ ( rows ) * ( columns ) * 6 ];
        
        for( int y = 0; y < rows + 1; y ++ ) {
            for( int x = 0; x < columns + 1; x ++ ) {
                int v = y * ( columns + 1 ) + x;
                vertices[v] = new Vector3( x * cellSize.x, y * cellSize.y, z );
                textureCoords[v] = new Vector2( (float)x / (float)columns, (float)y / (float)rows );
            }
        }
        for( int y = 0; y < rows; y ++ ) {
            for( int x = 0; x < columns; x ++ ) {
                int quadIndex = ( y * ( columns + 1) + x ) * 6;
                int vA = y * ( columns + 1 ) + x;
                int vB = vA + 1;
                int vC = ( y + 1 ) * ( columns + 1 ) + x;
                int vD = vC + 1;
                // first triangle.
                triangles[quadIndex++] = vA;
                triangles[quadIndex++] = vB;
                triangles[quadIndex++] = vC;
                // second triangle
                triangles[quadIndex++] = vB;
                triangles[quadIndex++] = vD;
                triangles[quadIndex++] = vC;
            }
        }
        mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.uv = textureCoords;
        mesh.triangles = triangles;
        mesh.RecalculateNormals(); mesh.RecalculateBounds;
        GetComponent<MeshFilter>().sharedMesh = mesh;
    }
}

It looks like your using x and z so you’d have to change the vertices[v] = new Vector3 part swapping y and z elements.

I’m just suggesting to make a mesh as big as you need it to be to cover the screen. Then you can use the mesh calculated by this component and update it as normal

thank you, translating this will be difficult but i’ll try

hey guys, thanks for all the help. I figured out almost everything I want to do…here is the product so far. :slight_smile:

Looks great. glad that script worked out alright. Wrote it entirely in the quick reply so was unsure about it but looks like you did something great with it.

yup, I have run into a problem though: even with optimization, there are still too many verts for the script to run through for it to be feasible. A friend mentioned this might be doable in what he called a “fragment shader”, but I have no idea how to write this. Ideally, I’d want the shader to give the same stretching effect and make the alpha more opaque as the stretching effect increased…

so…anyone have any ideas for that? this is proving to be a bit of a bear in terms of making it computationally feasible.