前提・実現したいこと
変換行列からPositionを取り出したい
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Linq; 5 6public class Example : MonoBehaviour 7{ 8 Matrix4x4[][] matrix4X4s; 9 Matrix4x4[] flatMatrix; 10 11 public Material material; 12 13 HashSet<Matrix4x4> matriHash = new HashSet<Matrix4x4>(); 14 15 private void Start() 16 { 17 int seed = Random.Range(-999999, 999999); 18 19 float[,] noiseMap = Noise.GenerateNoiseMap(200, 200, seed, 50, 4, 0.5f, 2, Vector2.zero); 20 21 int rows = 200; 22 int columns = 200; 23 24 flatMatrix = new Matrix4x4[rows * columns]; 25 26 for (int x = 0; x < rows; x++) 27 { 28 for (int y = 0; y < columns; y++) 29 { 30 float height = noiseMap[y, x]; 31 32 int index = (x * columns) + y; 33 34 Vector2 pos = new Vector2(x, y); 35 Quaternion rotation = Quaternion.identity; 36 Vector3 scale = Vector3.one; 37 38 if (height < 0.35f) 39 { 40 flatMatrix[index] = Matrix4x4.TRS(pos, rotation, scale); 41 matriHash.Add(flatMatrix[index]); 42 } 43 } 44 } 45 46 foreach (Matrix4x4 hash in matriHash) 47 { 48 var position = new Vector3(hash[0, 3], hash[1, 3], hash[2, 3]); 49 Vector2 pos = new Vector2(position.x, position.y); 50 posHash.Add(pos); 51 } 52 } 53 54 Vector2 getScreenDownLeft() 55 { 56 Vector2 pos = new Vector2(0, 0); 57 Vector2 downLeft = Camera.main.ScreenToWorldPoint(pos); 58 return downLeft; 59 } 60 61 Vector2 getScreenUpRight() 62 { 63 Vector2 pos = new Vector2(Screen.width, Screen.height); 64 Vector2 upRight = Camera.main.ScreenToWorldPoint(pos); 65 return upRight; 66 } 67 68 HashSet<Vector2> getScreenPos() 69 { 70 HashSet<Vector2> hash = new HashSet<Vector2>(); 71 72 for (int x = (int)getScreenDownLeft().x - 5; x < (int)getScreenUpRight().x + 5; x++) 73 { 74 for (int y = (int)getScreenDownLeft().y - 5; y < (int)getScreenUpRight().y + 5; y++) 75 { 76 Vector2 pos = new Vector2(x, y); 77 hash.Add(pos); 78 } 79 } 80 81 return hash; 82 } 83 84 Matrix4x4[] array = new Matrix4x4[1023]; 85 86 HashSet<Matrix4x4> hashMat = new HashSet<Matrix4x4>(); 87 88 HashSet<Vector2> posHash = new HashSet<Vector2>(); 89 90 private void Update() 91 { 92 foreach (Vector2 item in getScreenPos()) 93 { 94 GetMatrix(item); 95 } 96 97 foreach (var m in matrix4X4s) 98 { 99 Graphics.DrawMeshInstanced(MeshGenerator.basicMesh, 0, material, m); 100 } 101 } 102 103 Matrix4x4[][] GetMatrix(Vector2 pos) 104 { 105 if (posHash.Contains(pos)) 106 { 107 foreach(Matrix4x4 item in matriHash) 108 { 109 var position = new Vector2(item[0, 3], item[1, 3]); 110 Vector2 matriPos = new Vector2(position.x, position.y); 111 if(pos == matriPos) 112 { 113 hashMat.Add(item); 114 } 115 } 116 } 117 118 array = hashMat.ToArray(); 119 120 matrix4X4s = array.Select((m, i) => (m, i / 1023)) 121 .GroupBy(t => t.Item2) 122 .Select(g => g.Select(t => t.Item1).ToArray()).ToArray(); 123 124 return matrix4X4s; 125 } 126} 127
C#
1using UnityEngine; 2using System.Collections; 3 4public static class Noise 5{ 6 7 public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset) 8 { 9 float[,] noiseMap = new float[mapWidth, mapHeight]; 10 11 System.Random prng = new System.Random(seed); 12 Vector2[] octaveOffsets = new Vector2[octaves]; 13 for (int i = 0; i < octaves; i++) 14 { 15 float offsetX = prng.Next(-1000000, 1000000) + offset.x; 16 float offsetY = prng.Next(-1000000, 1000000) + offset.y; 17 octaveOffsets[i] = new Vector2(offsetX, offsetY); 18 } 19 20 if (scale <= 0) 21 { 22 scale = 0.0001f; 23 } 24 25 float maxNoiseHeight = float.MinValue; 26 float minNoiseHeight = float.MaxValue; 27 28 float halfWidth = mapWidth / 2f; 29 float halfHeight = mapHeight / 2f; 30 31 32 for (int y = 0; y < mapHeight; y++) 33 { 34 for (int x = 0; x < mapWidth; x++) 35 { 36 37 float amplitude = 1; 38 float frequency = 1; 39 float noiseHeight = 0; 40 41 for (int i = 0; i < octaves; i++) 42 { 43 float sampleX = (x - halfWidth) / scale * frequency + octaveOffsets[i].x; 44 float sampleY = (y - halfHeight) / scale * frequency + octaveOffsets[i].y; 45 46 float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1; 47 noiseHeight += perlinValue * amplitude; 48 49 amplitude *= persistance; 50 frequency *= lacunarity; 51 } 52 53 if (noiseHeight > maxNoiseHeight) 54 { 55 maxNoiseHeight = noiseHeight; 56 } 57 else if (noiseHeight < minNoiseHeight) 58 { 59 minNoiseHeight = noiseHeight; 60 } 61 noiseMap[x, y] = noiseHeight; 62 } 63 } 64 65 for (int y = 0; y < mapHeight; y++) 66 { 67 for (int x = 0; x < mapWidth; x++) 68 { 69 noiseMap[x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, y]); 70 } 71 } 72 73 return noiseMap; 74 } 75 76}
試したこと
カメラに映っているメッシュだけをGraphics.DrawMeshInstancedを使って描画したかったのですが、カメラに映っているワールド座標と、変換行列に代入されている座標を一致しているか確認する方法が、分からなかったため、質問しました。
【追記】
回答者様の回答をもとに、スクリプトを変更しました。
ですが、カメラに映っているメッシュだけを描画はしているのですが、0.1~0.3FPSしか出ません。
Graphics.DrawMeshのほうが軽いくらいです……。どのように書き換えたらよいでしょうか?

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/08/16 12:45