void ApplyBrush(DisplaceableSurface origin, RaycastHit rayHit, List <DisplaceableSurface> canvases) { // draw strokes foreach (var canvas in canvases) { Vector2 uv = rayHit.textureCoord; // adjust texture coordinates if (origin != canvas) { Vector3 dv = canvas.bounds.min - origin.bounds.min; uv.x -= dv.x / sliceSize.x; uv.y -= dv.z / sliceSize.y; } // actual brush drawing canvas.ApplyBrush(uv, brushMaterial, brushSize); } // DEBUG: // Leave this instead of foreach to test edges stitching //origin.ApplyBrush(rayHit.textureCoord, brushMaterial, brushSize); // stitch the edges StitchChain(canvases); }
// Update is called once per frame void Update() { // listen for mouse press if (!Input.GetKey(KeyCode.Mouse0)) { return; } // ray casting towards mesh RaycastHit rayHit; if (!Physics.Raycast(Camera.allCameras[0].ScreenPointToRay(Input.mousePosition), out rayHit)) { return; } // origin DisplaceableSurface origin = rayHit.transform.gameObject.GetComponent <DisplaceableSurface>(); if (null == origin) { return; } // distance check to add neighboring surfaces float checkDistance = brushSize * brushSize; List <DisplaceableSurface> toDraw = new List <DisplaceableSurface>(); toDraw.Add(origin); foreach (var surface in surfaces) { if (surface == origin) { continue; } var distance = surface.bounds.SqrDistance(rayHit.point); if (distance <= checkDistance) { toDraw.Add(surface); } } // draw ApplyBrush(origin, rayHit, toDraw); }
void OnWizardCreate() { // pre-compute some data int xTextures = Mathf.CeilToInt(totalWidth * texelsPerWorldUnit / textureSize); int zTextures = Mathf.CeilToInt(totalLength * texelsPerWorldUnit / textureSize); float segmentWidth = totalWidth / xTextures; float segmentLength = totalLength / zTextures; int xVerticiesPerSegment = Math.Max(2, Mathf.CeilToInt(segmentWidth / geometryResolution)); int zVerticiesPerSegment = Math.Max(2, Mathf.CeilToInt(segmentLength / geometryResolution)); // root object GameObject surfaceChain = new GameObject(); surfaceChain.transform.position = Vector3.zero; string surfaceName = optionalName; if (string.IsNullOrEmpty(surfaceName)) { surfaceName = "Surface Chain"; } surfaceName += " (" + xTextures + " x " + zTextures + " )"; surfaceChain.name = surfaceName; // prepare mesh Mesh mesh = CreateBaseMesh("Plane", xVerticiesPerSegment, zVerticiesPerSegment, segmentWidth, segmentLength); // make grid var grid = new DisplaceableSurface[xTextures, zTextures]; for (int z = 0; z < zTextures; ++z) { for (int x = 0; x < xTextures; ++x) { GameObject slice = new GameObject(); slice.name = "Slice (" + x.ToString() + ", " + z.ToString() + ")"; slice.isStatic = staticSlices; // add mesh and renderer var meshFilter = slice.AddComponent <MeshFilter>(); meshFilter.sharedMesh = mesh; var renderer = slice.AddComponent <MeshRenderer>(); renderer.material = surfaceMaterial; // surface var script = slice.AddComponent <DisplaceableSurface>(); script.textureFormat = textureFormat; script.maximumTextureSize = textureSize; // collider var collider = slice.AddComponent <MeshCollider>(); // save item and push to the parent grid[x, z] = script; slice.transform.parent = surfaceChain.transform; slice.transform.position = Vector3.zero; slice.transform.localPosition = new Vector3(x * mesh.bounds.size.x, 0, z * mesh.bounds.size.z); } } // link items on the grid for (int z = 0; z < zTextures - 1; ++z) { for (int x = 1; x < xTextures; ++x) { var current = grid[x, z]; var left = grid[x - 1, z]; var top = grid[x, z + 1]; current.leftNeighbour = left; current.topNeighbour = top; } } // manager var manager = surfaceChain.AddComponent <SurfaceChainManager>(); // done Selection.activeObject = surfaceChain; }