static void CreateColoredCubesVolume() { int width = 256; int height = 32; int depth = 256; ColoredCubesVolumeData data = VolumeDataAsset.CreateEmptyVolumeData <ColoredCubesVolumeData>(new Region(0, 0, 0, width - 1, height - 1, depth - 1)); GameObject coloredCubesGameObject = ColoredCubesVolume.CreateGameObject(data, true, true); // And select it, so the user can get straight on with editing. Selection.activeGameObject = coloredCubesGameObject; int floorThickness = 8; QuantizedColor floorColor = new QuantizedColor(192, 192, 192, 255); for (int z = 0; z <= depth - 1; z++) { for (int y = 0; y < floorThickness; y++) { for (int x = 0; x <= width - 1; x++) { data.SetVoxel(x, y, z, floorColor); } } } }
// Use this for initialization void Start() { // We'll store a reference to the colored cubes volume so we can interact with it later. coloredCubesVolume = gameObject.GetComponent<ColoredCubesVolume>(); if(coloredCubesVolume == null) { Debug.LogError("This 'ClickToDestroy' script should be attached to a game object with a ColoredCubesVolume component"); } }
/// Picks the last empty voxel lying on the ray. /** * */ public static bool PickLastEmptyVoxel(ColoredCubesVolume volume, Vector3 origin, Vector3 direction, float distance, out PickVoxelResult pickResult) { validateDistance(distance); // This 'out' value needs to be initialised even if we don't hit // anything (in which case it will be left at it's default value). pickResult = new PickVoxelResult(); // Can't hit it the volume if there's no data. if ((volume.data == null) || (volume.data.volumeHandle == null)) { return(false); } // Cubiquity's picking code works in volume space whereas we expose an interface that works in world // space (for consistancy with other Unity functions). Therefore we apply the inverse of the volume's // volume-to-world transform to the ray, to bring it from world space into volume space. // // Note that we do this by transforming the start and end points of the ray (rather than the direction // of the ray) as Unity's Transform.InverseTransformDirection method does not handle scaling. Vector3 target = origin + direction * distance; origin = volume.transform.InverseTransformPoint(origin); target = volume.transform.InverseTransformPoint(target); direction = target - origin; // Now call through to the Cubiquity dll to do the actual picking. pickResult = new PickVoxelResult(); uint hit = CubiquityDLL.PickLastEmptyVoxel((uint)volume.data.volumeHandle, origin.x, origin.y, origin.z, direction.x, direction.y, direction.z, out pickResult.volumeSpacePos.x, out pickResult.volumeSpacePos.y, out pickResult.volumeSpacePos.z); // The result is in volume space, but again it is more convienient for Unity users to have the result // in world space. Therefore we apply the volume's volume-to-world transform to the volume space position. pickResult.worldSpacePos = volume.transform.TransformPoint((Vector3)(pickResult.volumeSpacePos)); // Return true if we hit a surface. return(hit == 1); }
// Use this for initialization void Start() { //Save Tooth GameObject into the volume variable to access coloredCubesVol = gameObject.GetComponent<ColoredCubesVolume>(); //Save Region as a variable to access outer corners of array Region theWholeRegion = coloredCubesVol.data.enclosingRegion; //Debug.Log (theWholeRegion.lowerCorner.x); and y..z...and uppercorner etc. //loop through an array of the enclosing region to figure out total numbers of certain colors. for (int arrayX = theWholeRegion.lowerCorner.x; arrayX <= theWholeRegion.upperCorner.x; arrayX++) { for(int arrayY = theWholeRegion.lowerCorner.y; arrayY <= theWholeRegion.upperCorner.y; arrayY++){ for(int arrayZ = theWholeRegion.lowerCorner.z; arrayZ <= theWholeRegion.upperCorner.z; arrayZ++){ //save currentVoxel we are on's color QuantizedColor currentColor = coloredCubesVol.data.GetVoxel(arrayX,arrayY,arrayZ); //test the colorS if(currentColor.red == 248 && currentColor.green == 252 && currentColor.blue == 200){ totalWhite++; }else if(currentColor.red == 24 && currentColor.green == 20 && currentColor.blue == 8){ totalBlack++; }else if(currentColor.red == 112 && currentColor.green == 28 && currentColor.blue == 0){ totalBrown++; }else if(currentColor.red == 152 && currentColor.green == 152 && currentColor.blue == 0){ totalYellow++; }else{ } } } } //Debug.Log ("TOTAL YELLOW"); //Debug.Log ((deletedYellow/totalYellow)*100); //Debug.Log ("TOTAL BROWN"); //Debug.Log (totalBrown); //Debug.Log ("TOTAL BLACK"); //Debug.Log (totalBlack); //Debug.Log ("TOTAL White"); //Debug.Log (totalWhite); }
/// Picks the first solid voxel lying on the ray. /** * */ public static bool PickFirstSolidVoxel(ColoredCubesVolume volume, Vector3 origin, Vector3 direction, float distance, out PickVoxelResult pickResult) { validateDistance(distance); // This 'out' value needs to be initialised even if we don't hit // anything (in which case it will be left at it's default value). pickResult = new PickVoxelResult(); // Can't hit it the volume if there's no data. if((volume.data == null) || (volume.data.volumeHandle == null)) { return false; } // Cubiquity's picking code works in volume space whereas we expose an interface that works in world // space (for consistancy with other Unity functions). Therefore we apply the inverse of the volume's // volume-to-world transform to the ray, to bring it from world space into volume space. // // Note that we do this by transforming the start and end points of the ray (rather than the direction // of the ray) as Unity's Transform.InverseTransformDirection method does not handle scaling. Vector3 target = origin + direction * distance; origin = volume.transform.InverseTransformPoint(origin); target = volume.transform.InverseTransformPoint(target); direction = target - origin; // Now call through to the Cubiquity dll to do the actual picking. uint hit = CubiquityDLL.PickFirstSolidVoxel((uint)volume.data.volumeHandle, origin.x, origin.y, origin.z, direction.x, direction.y, direction.z, out pickResult.volumeSpacePos.x, out pickResult.volumeSpacePos.y, out pickResult.volumeSpacePos.z); // The result is in volume space, but again it is more convienient for Unity users to have the result // in world space. Therefore we apply the volume's volume-to-world transform to the volume space position. pickResult.worldSpacePos = volume.transform.TransformPoint((Vector3)(pickResult.volumeSpacePos)); // Return true if we hit a surface. return hit == 1; }
/// Convinience method for creating a GameObject with a set of colored cubes components attached. /** * Adding a volume to a scene requires creating a GameObject and then attching the required Cubiquity components such a renderer and a * collider. This method simply automates the process and also attaches the provided volume data. * * \param data The volume data which should be attached to the construced volume. * \param addRenderer Specifies whether a renderer component should be added so that the volume is displayed. * \param addCollider Specifies whether a collider component should be added so that the volume can participate in collisions. */ public static GameObject CreateGameObject(ColoredCubesVolumeData data, bool addRenderer, bool addCollider) { // Create our main game object representing the volume. GameObject coloredCubesVolumeGameObject = new GameObject("Colored Cubes Volume"); //Add the required volume component. ColoredCubesVolume coloredCubesVolume = coloredCubesVolumeGameObject.GetOrAddComponent <ColoredCubesVolume>(); // Set the provided data. coloredCubesVolume.data = data; // Add the renderer and collider if desired. if (addRenderer) { coloredCubesVolumeGameObject.AddComponent <ColoredCubesVolumeRenderer>(); } if (addCollider) { coloredCubesVolumeGameObject.AddComponent <ColoredCubesVolumeCollider>(); } // Return the created object return(coloredCubesVolumeGameObject); }
/// Picks the last empty voxel lying on the ray. /** * */ public static bool PickLastEmptyVoxel(ColoredCubesVolume volume, Ray ray, float distance, out PickVoxelResult pickResult) { return(PickLastEmptyVoxel(volume, ray.origin, ray.direction, distance, out pickResult)); }
public void OnEnable() { coloredCubesVolume = target as ColoredCubesVolume; }
// This funcion should be implemented to find the point where the ray // pierces the mesh, between the last empty voxel and the first solid voxel. /*public static bool PickSurface(ColoredCubesVolume volume, Vector3 origin, Vector3 direction, float distance, PickSurfaceResult pickResult) { }*/ /// Picks the first solid voxel lying on the ray. /** * */ public static bool PickFirstSolidVoxel(ColoredCubesVolume volume, Ray ray, float distance, out PickVoxelResult pickResult) { return PickFirstSolidVoxel(volume, ray.origin, ray.direction, distance, out pickResult); }