//in main thread //generate voxels public void CollectUsingComputeShader() { float maxSlopeCos = Mathf.Cos((float)((double)template.maxSlope * Math.PI / 180.0)); for (int i = 0; i < templates.Count; i++) { MeshColliderInfo curInfo = templates[i]; Vector3 offsetedPos = template.realOffsetedPosition; CSRasterization3DResult result = PathFinder.scene.Rasterize3D( curInfo.verts, curInfo.tris, curInfo.bounds, curInfo.matrix, template.lengthX_extra, template.lengthZ_extra, offsetedPos.x, offsetedPos.z, template.voxelSize, maxSlopeCos); if (result != null) { templatesAfterComputeShader.Add(new RData(curInfo, result)); } } }
public void CollectUsingComputeShader() { float maxSlopeCos = Mathf.Cos((float)((double)template.maxSlope * Math.PI / 180.0)); int vSizeX = template.lengthX_extra; int vSizeZ = template.lengthZ_extra; Vector3 realChunkPos = template.realOffsetedPosition; float chunkPosX = realChunkPos.x; float chunkPosZ = realChunkPos.z; foreach (var terrain in terrainsInfo) { //int hSizeX = terrain.hSizeX; //int hSizeZ = terrain.hSizeZ; //int resolution = terrain.resolution; //float[,] heightMap = terrain.heightMap; //Matrix4x4 heightMatrix = terrain.heightMatrix; Vector3[] verts; int[] tris; base.GetTerrainMesh(terrain, out verts, out tris); //Volume terrainVolume; //if (terrain.alphaMap != null) // terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, terrain.possibleArea); //else // terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, defaultArea); //terrainVolume.terrain = true; CSRasterization2DResult resultTerrain = PathFinder.scene.Rasterize2D(verts, tris, vSizeX, vSizeZ, chunkPosX, chunkPosZ, template.voxelSize, maxSlopeCos); CSRasterization3DResult[] resultTrees = null; List <Bounds> treeData = terrain.treeData; if (treeData != null && treeData.Count > 0) { resultTrees = new CSRasterization3DResult[treeData.Count]; for (int i = 0; i < treeData.Count; i++) { Bounds bound = treeData[i]; Matrix4x4 m = Matrix4x4.TRS(bound.center, Quaternion.identity, new Vector3(bound.size.x, bound.size.y * 0.5f, bound.size.z)); resultTrees[i] = PathFinder.scene.Rasterize3D(fancyVerts, fancyTris, bound, m, vSizeX, vSizeZ, chunkPosX, chunkPosZ, template.voxelSize, maxSlopeCos); } } _collectedTerrainUsingComputeShader.Add(new TerrainInfoCSR(terrain, resultTerrain, resultTrees)); } }
//for compute shaders public void AppendComputeShaderResult(CSRasterization3DResult data, Area area) { Voxel3D[] voxels = data.voxels; int voxelsX = data.voxelsX; //int voxelsY = data.voxelsY; int volumeStartX = data.volumeStartX; int volumeStartZ = data.volumeStartZ; int volumeSizeX = data.volumeSizeX; int volumeSizeZ = data.volumeSizeZ; byte areaValue = GetAreaValue(area); for (int x = 0; x < volumeSizeX; x++) { for (int z = 0; z < volumeSizeZ; z++) { var curVoxel = voxels[(z * voxelsX) + x]; if (curVoxel.passability != -1) { SetVoxel(volumeStartX + x, volumeStartZ + z, curVoxel.min, curVoxel.max, (sbyte)curVoxel.passability, areaValue); } } } }
private void AddColliderGenericGPU(Collider collider) { Matrix4x4 matrix = Matrix4x4.identity; Transform colliderTransform = collider.transform; Vector3[] verts = null; int[] tris = null; Bounds bounds = collider.bounds; if (collider is BoxCollider) { verts = cubeVerts; tris = cubeTris; matrix = Matrix4x4.TRS(bounds.center, colliderTransform.rotation, Vector3.Scale(colliderTransform.lossyScale, (collider as BoxCollider).size)); } else if (collider is SphereCollider) { verts = sphereVerts; tris = sphereTris; float r = bounds.extents.x / 0.5f; matrix = Matrix4x4.TRS(bounds.center, Quaternion.identity, new Vector3(r, r, r)); } else if (collider is CapsuleCollider) { tris = capsuleTris; verts = new Vector3[capsuleVerts.Length]; CapsuleCollider capsuleCollider = collider as CapsuleCollider; Vector3 lossyScale = colliderTransform.lossyScale; float height = capsuleCollider.height * lossyScale.y; float radius = capsuleCollider.radius * Mathf.Max(lossyScale.x, lossyScale.z); float size = Mathf.Max(1f, height / (radius * 2f)) - 2f; Matrix4x4 capsuleShapeMatrix = Matrix4x4.Scale(new Vector3(radius * 2f, radius * 2f, radius * 2f)); for (int index = 0; index < verts.Length; ++index) { if (capsuleVerts[index].y > 0.0) { verts[index] = capsuleShapeMatrix.MultiplyPoint( new Vector3( capsuleVerts[index].x, Mathf.Max((float)(capsuleVerts[index].y + size * 0.5), 0.0f), capsuleVerts[index].z)); } else if (capsuleVerts[index].y < 0.0) { verts[index] = capsuleShapeMatrix.MultiplyPoint( new Vector3( capsuleVerts[index].x, Mathf.Min((float)(capsuleVerts[index].y - size * 0.5), 0.0f), capsuleVerts[index].z)); } } matrix = Matrix4x4.TRS( capsuleCollider.bounds.center, //actual world position colliderTransform.rotation * //world rotation Quaternion.Euler( //plus capsule orientation capsuleCollider.direction == 2 ? 90f : 0.0f, 0.0f, capsuleCollider.direction == 0 ? 90f : 0.0f), Vector3.one); } else if (collider is CharacterController) { tris = capsuleTris; verts = new Vector3[capsuleVerts.Length]; CharacterController charControler = collider as CharacterController; Vector3 lossyScale = colliderTransform.lossyScale; float height = charControler.height * lossyScale.y; float radius = charControler.radius * Mathf.Max(lossyScale.x, lossyScale.z); float size = Mathf.Max(1f, height / (radius * 2f)) - 2f; Matrix4x4 capsuleShapeMatrix = Matrix4x4.Scale(new Vector3(radius * 2f, radius * 2f, radius * 2f)); for (int index = 0; index < verts.Length; ++index) { if (capsuleVerts[index].y > 0.0) { verts[index] = capsuleShapeMatrix.MultiplyPoint(new Vector3(capsuleVerts[index].x, Mathf.Max((float)(capsuleVerts[index].y + size * 0.5), 0.0f), capsuleVerts[index].z)); } else if (capsuleVerts[index].y < 0.0) { verts[index] = capsuleShapeMatrix.MultiplyPoint(new Vector3(capsuleVerts[index].x, Mathf.Min((float)(capsuleVerts[index].y - size * 0.5), 0.0f), capsuleVerts[index].z)); } } matrix = Matrix4x4.TRS(charControler.bounds.center, colliderTransform.rotation, Vector3.one); } else if (collider is MeshCollider) { Mesh curMesh = (collider as MeshCollider).sharedMesh; verts = curMesh.vertices; tris = curMesh.triangles; matrix = colliderTransform.localToWorldMatrix; } else { Debug.LogFormat("hey i dont know wich collider type is on {0}. please tell developer to fix that.", collider.gameObject.name); return; } var gameObjectArea = collider.transform.GetComponent <AreaGameObject>(); Area area; if (gameObjectArea != null) { area = PathFinder.GetArea(gameObjectArea.areaInt); } else { if (PathFinder.settings.checkRootTag) { area = PathFinderSettings.tagAssociations[collider.transform.root.tag]; } else { area = PathFinderSettings.tagAssociations[collider.transform.tag]; } } if (verts != null & tris != null) { float maxSlopeCos = Mathf.Cos(template.maxSlope * Mathf.PI / 180f); Vector3 offsetedPos = template.realOffsetedPosition; CSRasterization3DResult result = PathFinder.sceneInstance.Rasterize3D( verts, tris, bounds, matrix, template.lengthX_extra, template.lengthZ_extra, offsetedPos.x, offsetedPos.z, template.voxelSize, maxSlopeCos, false, false); if (result != null) { collectedComputeShaderData.Add(new ComputeShaderResultHolder(result, ColliderInfoMode.Solid, area)); } } }
public ComputeShaderResultHolder(CSRasterization3DResult result, ColliderInfoMode infoMode, Area area) { this.result = result; this.infoMode = infoMode; this.area = area; }
public RData(MeshColliderInfo info, CSRasterization3DResult result) { this.info = info; this.result = result; }