public ObiHeightFieldHandle GetOrCreateHeightField(TerrainData source) { ObiHeightFieldHandle handle; if (!handles.TryGetValue(source, out handle)) { // Get the heighfield into a 1d array: int width = source.heightmapResolution; int height = source.heightmapResolution; float[,] heights = source.GetHeights(0, 0, width, height); float[] buffer = new float[width * height]; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { buffer[y * width + x] = heights[y, x]; } } handle = new ObiHeightFieldHandle(source, headers.count); handles.Add(source, handle); headers.Add(new HeightFieldHeader(samples.count, buffer.Length)); samples.AddRange(buffer); } return(handle); }
public override bool UpdateIfNeeded() { TerrainCollider terrain = collider as TerrainCollider; // retrieve collision world and index: var world = ObiColliderWorld.GetInstance(); int index = source.Handle.index; int resolution = terrain.terrainData.heightmapResolution; // get or create the heightfield: if (handle == null || !handle.isValid) { handle = world.GetOrCreateHeightField(terrain.terrainData); handle.Reference(); } // update collider: var shape = world.colliderShapes[index]; shape.type = ColliderShape.ShapeType.Heightmap; shape.phase = source.Phase; shape.flags = terrain.isTrigger ? 1 : 0; shape.rigidbodyIndex = source.Rigidbody != null ? source.Rigidbody.handle.index : -1; shape.materialIndex = source.CollisionMaterial != null ? source.CollisionMaterial.handle.index : -1; shape.contactOffset = terrain.contactOffset + source.Thickness; shape.dataIndex = handle.index; shape.size = terrain.terrainData.size; shape.center = new Vector4(resolution, resolution, resolution, resolution); world.colliderShapes[index] = shape; // update bounds: var aabb = world.colliderAabbs[index]; aabb.FromBounds(terrain.bounds, shape.contactOffset); world.colliderAabbs[index] = aabb; // update transform: var trfm = world.colliderTransforms[index]; trfm.FromTransform(terrain.transform); world.colliderTransforms[index] = trfm; return(true); }
public void DestroyHeightField(ObiHeightFieldHandle handle) { if (handle != null && handle.isValid && handle.index < handles.Count) { var header = headers[handle.index]; // Update headers: for (int i = 0; i < headers.count; ++i) { var h = headers[i]; if (h.firstSample > header.firstSample) { h.firstSample -= header.sampleCount; headers[i] = h; } } // update handles: foreach (var pair in handles) { if (pair.Value.index > handle.index) { pair.Value.index--; } } // Remove nodes samples.RemoveRange(header.firstSample, header.sampleCount); // remove header: headers.RemoveAt(handle.index); // remove the heightfield from the dictionary: handles.Remove(handle.owner); // Invalidate our handle: handle.Invalidate(); } }
public void DestroyHeightField(ObiHeightFieldHandle hfHandle) { heightFieldContainer.DestroyHeightField(hfHandle); }