//what the devil is a nodeHandle? public override Mesh BuildMeshFromNodeHandle(uint nodeHandle) { Debug.Log("Trying to build ColoredCubes mesh from node"); // Create rendering and possible collision meshes. Mesh collisionMesh = new Mesh(); collisionMesh.hideFlags = HideFlags.DontSave; // Get the data from Cubiquity. int[] indices = CubiquityDLL.GetIndices(nodeHandle); ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle); // Create the arrays which we'll copy the data to. Vector3[] vertices = new Vector3[cubiquityVertices.Length]; for (int ct = 0; ct < cubiquityVertices.Length; ct++) { // Get the vertex data from Cubiquity. vertices[ct] = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z); } //FIXME - set collision mesh bounds as we do with rendering mesh? collisionMesh.vertices = vertices; collisionMesh.triangles = indices; Debug.Log("Collision Mesh Built from verticies of length: " + cubiquityVertices.Length.ToString()); return(collisionMesh); }
public static bool PickLastEmptyVoxel(CogBlockVolume volume, Vector3 origin, Vector3 direction, float distance, out PickVoxelResult pickResult) { // 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); } //again, transforming to volume space 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); //transform back out into worldspace pickResult.worldSpacePos = volume.transform.TransformPoint((Vector3)(pickResult.volumeSpacePos)); // Return true if we hit a surface. return(hit == 1); }
public override void DiscardChanges() { if (!IsVolumeHandleNull()) { CubiquityDLL.DiscardOverrideChunks(volumeHandle.Value); } }
/// \cond protected override void Synchronize() { base.Synchronize(); // Syncronize the mesh data. if (data != null) { if (data.volumeHandle.HasValue) { CubiquityDLL.UpdateVolumeMC(data.volumeHandle.Value); if (CubiquityDLL.HasRootOctreeNodeMC(data.volumeHandle.Value) == 1) { uint rootNodeHandle = CubiquityDLL.GetRootOctreeNodeMC(data.volumeHandle.Value); if (rootOctreeNodeGameObject == null) { rootOctreeNodeGameObject = OctreeNode.CreateOctreeNode(rootNodeHandle, gameObject); } OctreeNode rootOctreeNode = rootOctreeNodeGameObject.GetComponent <OctreeNode>(); int nodeSyncsPerformed = rootOctreeNode.syncNode(maxNodesPerSync, gameObject); // If no node were syncronized then the mesh data is up to // date and we can set the flag to convey this to the user. isMeshSyncronized = (nodeSyncsPerformed == 0); } } } }
public static bool PickFirstSolidVoxel(CogBlockVolume volume, Vector3 origin, Vector3 direction, float distance, out PickVoxelResult pickResult) { //initialization of an empty struct pickResult = new PickVoxelResult(); // Can't hit it the volume if there's no data. if ((volume.data == null) || (volume.data.volumeHandle == null)) { return(false); } //As noted by cubiquity, where cubqity's picking code works in volume space, Unity needs to work in world space... // Cubiquity's picking code works in volume space whereas we expose an interface that works in world //Grab our ray's components and transform them for volume space. 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. //Recall that CubiquityDLL will only have to work with ColoredCubeData, but that we are translating that boldface into CogBlockVolume data. 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); }
public override Mesh BuildMeshFromNodeHandle(uint nodeHandle) { // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C // Create rendering and possible collision meshes. Mesh collisionMesh = new Mesh(); collisionMesh.hideFlags = HideFlags.DontSave; // Get the data from Cubiquity. int[] indices = CubiquityDLL.GetIndices(nodeHandle); ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle); // Create the arrays which we'll copy the data to. Vector3[] vertices = new Vector3[cubiquityVertices.Length]; for (int ct = 0; ct < cubiquityVertices.Length; ct++) { // Get the vertex data from Cubiquity. vertices[ct] = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z); } //FIXME - set collision mesh bounds as we do with rendering mesh? collisionMesh.vertices = vertices; collisionMesh.triangles = indices; return(collisionMesh); }
/// \cond protected override void InitializeEmptyCubiquityVolume(Region region) { // We check 'mVolumeHandle' instead of 'volumeHandle' as the getter for the latter will in turn call this method. if (mVolumeHandle != null) { Debug.LogAssertion("Volume handle should be null prior to initializing volume"); return; } if (!initializeAlreadyFailed) // If it failed before it will fail again - avoid spamming error messages. { try { // Create an empty region of the desired size. volumeHandle = CubiquityDLL.NewEmptyColoredCubesVolume(region.lowerCorner.x, region.lowerCorner.y, region.lowerCorner.z, region.upperCorner.x, region.upperCorner.y, region.upperCorner.z, fullPathToVoxelDatabase, DefaultBaseNodeSize); } catch (CubiquityException exception) { volumeHandle = null; initializeAlreadyFailed = true; Debug.LogException(exception); Debug.LogError("Failed to open voxel database '" + fullPathToVoxelDatabase + "'"); } } }
public override Mesh BuildMeshFromNodeHandle(uint nodeHandle) { Mesh collisionMesh = new Mesh(); collisionMesh.hideFlags = HideFlags.DontSave; // Get the data from Cubiquity. int[] indices = CubiquityDLL.GetIndicesMC(nodeHandle); TerrainVertex[] cubiquityVertices = CubiquityDLL.GetVerticesMC(nodeHandle); // Create the arrays which we'll copy the data to. Vector3[] vertices = new Vector3[cubiquityVertices.Length]; for (int ct = 0; ct < cubiquityVertices.Length; ct++) { // Get the vertex data from Cubiquity. vertices[ct] = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z); vertices[ct] *= (1.0f / 256.0f); } // Assign vertex data to the meshes. collisionMesh.vertices = vertices; collisionMesh.triangles = indices; return(collisionMesh); }
/// \endcond /// \cond public override void InitializeExistingCubiquityVolume() { // This function might get called multiple times. E.g the user might call it striaght after crating the volume (so // they can add some initial data to the volume) and it might then get called again by OnEnable(). Handle this safely. if (volumeHandle == null) { // Create an empty region of the desired size. volumeHandle = CubiquityDLL.NewTerrainVolumeFromVDB(fullPathToVoxelDatabase, DefaultBaseNodeSize); } }
public Mesh BuildMeshFromNodeHandleForTerrainVolume(uint nodeHandle) { // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C // Create rendering and possible collision meshes. Mesh renderingMesh = new Mesh(); renderingMesh.hideFlags = HideFlags.DontSave; // Get the data from Cubiquity. int[] indices = CubiquityDLL.GetIndicesMC(nodeHandle); TerrainVertex[] cubiquityVertices = CubiquityDLL.GetVerticesMC(nodeHandle); // Create the arrays which we'll copy the data to. Vector3[] renderingVertices = new Vector3[cubiquityVertices.Length]; Vector3[] renderingNormals = new Vector3[cubiquityVertices.Length]; Color32[] renderingColors = new Color32[cubiquityVertices.Length]; //Vector4[] renderingTangents = new Vector4[cubiquityVertices.Length]; Vector2[] renderingUV = new Vector2[cubiquityVertices.Length]; Vector2[] renderingUV2 = new Vector2[cubiquityVertices.Length]; for (int ct = 0; ct < cubiquityVertices.Length; ct++) { // Get the vertex data from Cubiquity. Vector3 position = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z); Vector3 normal = new Vector3(cubiquityVertices[ct].nx, cubiquityVertices[ct].ny, cubiquityVertices[ct].nz); Color32 color = new Color32(cubiquityVertices[ct].m0, cubiquityVertices[ct].m1, cubiquityVertices[ct].m2, cubiquityVertices[ct].m3); //Vector4 tangents = new Vector4(cubiquityVertices[ct].m4 / 255.0f, cubiquityVertices[ct].m5 / 255.0f, cubiquityVertices[ct].m6 / 255.0f, cubiquityVertices[ct].m7 / 255.0f); Vector2 uv = new Vector2(cubiquityVertices[ct].m4 / 255.0f, cubiquityVertices[ct].m5 / 255.0f); Vector2 uv2 = new Vector2(cubiquityVertices[ct].m6 / 255.0f, cubiquityVertices[ct].m7 / 255.0f); // Copy it to the arrays. renderingVertices[ct] = position; renderingNormals[ct] = normal; renderingColors[ct] = color; //renderingTangents[ct] = tangents; renderingUV[ct] = uv; renderingUV2[ct] = uv2; } // Assign vertex data to the meshes. renderingMesh.vertices = renderingVertices; renderingMesh.normals = renderingNormals; renderingMesh.colors32 = renderingColors; //renderingMesh.tangents = renderingTangents; renderingMesh.uv = renderingUV; renderingMesh.uv2 = renderingUV2; renderingMesh.triangles = indices; // FIXME - Get proper bounds renderingMesh.bounds.SetMinMax(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(32.0f, 32.0f, 32.0f)); return(renderingMesh); }
public static void BuildMeshFromNodeHandleForColoredCubesVolume(Mesh mesh, uint nodeHandle, bool onlyPositions) { // Get the data from Cubiquity. ColoredCubesVertex[] vertices; ushort[] indices; CubiquityDLL.GetMesh <ColoredCubesVertex>(nodeHandle, out vertices, out indices); int noOfVertices = vertices.Length; int noOfIndices = indices.Length; #endif // Cubiquity uses 16-bit index arrays to save space, and it appears Unity does the same (at least, there is // a limit of 65535 vertices per mesh). However, the Mesh.triangles property is of the signed 32-bit int[] // type rather than the unsigned 16-bit ushort[] type. Perhaps this is so they can switch to 32-bit index // buffers in the future? At any rate, it means we have to perform a conversion. int[] indicesAsInt = new int[noOfIndices]; for (int ct = 0; ct < noOfIndices; ct++) { indicesAsInt[ct] = indices[ct]; } // Clear any previous mesh data. mesh.Clear(true); // Required for the CubicVertex decoding process. Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f); // Copy the vertex positions from Cubiquity into the Unity mesh. Vector3[] positions = new Vector3[noOfVertices]; for (int ct = 0; ct < noOfVertices; ct++) { // Get and decode the position positions[ct].Set(vertices[ct].x, vertices[ct].y, vertices[ct].z); positions[ct] -= offset; } // Assign vertex data to the mesh. mesh.vertices = positions; // For collision meshes the vertex positions are enough, but // for meshes which are rendered we want all vertex attributes. if (!onlyPositions) { Color32[] colors32 = new Color32[noOfVertices]; for (int ct = 0; ct < noOfVertices; ct++) { // Get and decode the color colors32[ct] = (Color32)vertices[ct].color; } // Assign vertex data to the mesh. mesh.colors32 = colors32; } // Assign index data to the mesh. mesh.triangles = indicesAsInt; }
/// \cond protected override void InitializeEmptyCubiquityVolume(Region region) { // This function might get called multiple times. E.g the user might call it striaght after crating the volume (so // they can add some initial data to the volume) and it might then get called again by OnEnable(). Handle this safely. if (volumeHandle == null) { // Create an empty region of the desired size. volumeHandle = CubiquityDLL.NewEmptyTerrainVolume(region.lowerCorner.x, region.lowerCorner.y, region.lowerCorner.z, region.upperCorner.x, region.upperCorner.y, region.upperCorner.z, fullPathToVoxelDatabase, DefaultBaseNodeSize); } }
/// Sets the material weights of the specified position. /** * \param x The 'x' position of the voxel to set. * \param y The 'y' position of the voxel to set. * \param z The 'z' position of the voxel to set. * \param materialSet The material weights the voxel should be set to. */ public void SetVoxel(int x, int y, int z, MaterialSet materialSet) { if (volumeHandle.HasValue) { if (x >= enclosingRegion.lowerCorner.x && y >= enclosingRegion.lowerCorner.y && z >= enclosingRegion.lowerCorner.z && x <= enclosingRegion.upperCorner.x && y <= enclosingRegion.upperCorner.y && z <= enclosingRegion.upperCorner.z) { CubiquityDLL.SetVoxelMC(volumeHandle.Value, x, y, z, materialSet); } } }
/// <summary> /// Initializes the GameObject to which a new node will belong, and does not have to be called by the average Editor-User. Already called in CreateOctreeNode, immediately after InitializeNode. /// It may be overwritten with care (nodeHandle is particularly important). /// </summary> /// <param name="nodeHandle">The CubiquityDLL handle of the node we're creating. </param> protected virtual void InitializeNode(uint nodeHandle) { //DIS IS VEDDY, VEDDY IMPORTANT. Without this, we can do nothing. NOTHING! Call super to let this happpen! this.nodeHandle = nodeHandle; //All Octree nodes have positions. Let's get ours in 3 easy steps. int nx, ny, nz; CubiquityDLL.GetNodePosition(nodeHandle, out nx, out ny, out nz); lowerCorner = new Vector3(nx, ny, nz); }
/// Sets the color of the specified position. /** * \param x The 'x' position of the voxel to set. * \param y The 'y' position of the voxel to set. * \param z The 'z' position of the voxel to set. * \param quantizedColor The color the voxel should be set to. */ public void SetVoxel(int x, int y, int z, QuantizedColor quantizedColor) { if (volumeHandle.HasValue) { if (x >= enclosingRegion.lowerCorner.x && y >= enclosingRegion.lowerCorner.y && z >= enclosingRegion.lowerCorner.z && x <= enclosingRegion.upperCorner.x && y <= enclosingRegion.upperCorner.y && z <= enclosingRegion.upperCorner.z) { CubiquityDLL.SetVoxel(volumeHandle.Value, x, y, z, quantizedColor); } } }
/// Gets the color of the specified position. /** * \param x The 'x' position of the voxel to get. * \param y The 'y' position of the voxel to get. * \param z The 'z' position of the voxel to get. * \return The color of the voxel. */ public QuantizedColor GetVoxel(int x, int y, int z) { // The initialization can fail (bad filename, database locked, etc), so the volume handle could still be null. if (volumeHandle.HasValue) { return(CubiquityDLL.GetQuantizedColorVoxel(volumeHandle.Value, x, y, z)); } else { return(new QuantizedColor()); } }
/// Sets the color of the specified position. /** * \param x The 'x' position of the voxel to set. * \param y The 'y' position of the voxel to set. * \param z The 'z' position of the voxel to set. * \param quantizedColor The color the voxel should be set to. */ public void SetVoxel(int x, int y, int z, QuantizedColor quantizedColor) { // The initialization can fail (bad filename, database locked, etc), so the volume handle could still be null. if (volumeHandle.HasValue) { if (x >= enclosingRegion.lowerCorner.x && y >= enclosingRegion.lowerCorner.y && z >= enclosingRegion.lowerCorner.z && x <= enclosingRegion.upperCorner.x && y <= enclosingRegion.upperCorner.y && z <= enclosingRegion.upperCorner.z) { CubiquityDLL.SetVoxel(volumeHandle.Value, x, y, z, quantizedColor); } } }
public override void CommitChanges() { if (!IsVolumeHandleNull()) { if (writePermissions == WritePermissions.ReadOnly) { throw new InvalidOperationException("Cannot commit changes to read-only voxel database (" + fullPathToVoxelDatabase + ")"); } CubiquityDLL.AcceptOverrideChunks(volumeHandle.Value); //We can discard the chunks now that they have been accepted. CubiquityDLL.DiscardOverrideChunks(volumeHandle.Value); } }
/// <summary> /// Builds the Mesh represented by the Node. Uses the Node's nodeHandle (inherited from OctreeNodeAlt) /// </summary> /// <returns>The mesh.</returns> public override Mesh BuildMesh() { // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f); // Required for the CubicVertex decoding process. // Meshes for rendering and collition. Mesh mesh = new Mesh(); //prevents memory leaks >:) mesh.hideFlags = HideFlags.DontSave; // Get the data from where it is stored in Cubiquity. int[] indices = CubiquityDLL.GetIndices(nodeHandle); ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle); // Create the arrays which we'll copy the data to. Vector3[] rendererVertices = new Vector3[cubiquityVertices.Length]; Color32[] rendererColors = new Color32[cubiquityVertices.Length]; //translate the data from Cubiquity's forms to Unity's for (int ct = 0; ct < cubiquityVertices.Length; ct++) { // Get the vertex data from Cubiquity. Vector3 position = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z); // Part of the CubicVertex decoding process. position -= offset; //nab the color QuantizedColor color = cubiquityVertices[ct].color; // Copy it to the arrays. rendererVertices[ct] = position; rendererColors[ct] = (Color32)color; } // Assign vertex data to the meshes. mesh.vertices = rendererVertices; mesh.colors32 = rendererColors; mesh.triangles = indices; // FIXME - Get proper bounds mesh.bounds.SetMinMax(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(32.0f, 32.0f, 32.0f)); mesh.name = "nodeHandle: " + nodeHandle.ToString(); return(mesh); //return null; }
/// Gets the material weights of the specified position. /** * \param x The 'x' position of the voxel to get. * \param y The 'y' position of the voxel to get. * \param z The 'z' position of the voxel to get. * \return The material weights of the voxel. */ public MaterialSet GetVoxel(int x, int y, int z) { MaterialSet materialSet; if (volumeHandle.HasValue) { CubiquityDLL.GetVoxelMC(volumeHandle.Value, x, y, z, out materialSet); } else { // Should maybe throw instead? materialSet = new MaterialSet(); } return(materialSet); }
/// Gets the color of the specified position. /** * \param x The 'x' position of the voxel to get. * \param y The 'y' position of the voxel to get. * \param z The 'z' position of the voxel to get. * \return The color of the voxel. */ public QuantizedColor GetVoxel(int x, int y, int z) { QuantizedColor result; if (volumeHandle.HasValue) { CubiquityDLL.GetVoxel(volumeHandle.Value, x, y, z, out result); } else { //Should maybe throw instead. result = new QuantizedColor(); } return(result); }
public static GameObject CreateOctreeNode(uint nodeHandle, GameObject parentGameObject) { int xPos, yPos, zPos; //Debug.Log("Getting position for node handle = " + nodeHandle); CubiquityDLL.GetNodePosition(nodeHandle, out xPos, out yPos, out zPos); StringBuilder name = new StringBuilder("(" + xPos + ", " + yPos + ", " + zPos + ")"); GameObject newGameObject = new GameObject(name.ToString()); newGameObject.AddComponent <OctreeNode>(); OctreeNode octreeNode = newGameObject.GetComponent <OctreeNode>(); octreeNode.lowerCorner = new Vector3(xPos, yPos, zPos); octreeNode.nodeHandle = nodeHandle; if (parentGameObject) { newGameObject.layer = parentGameObject.layer; newGameObject.transform.parent = parentGameObject.transform; newGameObject.transform.localPosition = new Vector3(); newGameObject.transform.localRotation = new Quaternion(); newGameObject.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); OctreeNode parentOctreeNode = parentGameObject.GetComponent <OctreeNode>(); if (parentOctreeNode != null) { Vector3 parentLowerCorner = parentOctreeNode.lowerCorner; newGameObject.transform.localPosition = octreeNode.lowerCorner - parentLowerCorner; } else { newGameObject.transform.localPosition = octreeNode.lowerCorner; } } else { newGameObject.transform.localPosition = octreeNode.lowerCorner; } newGameObject.hideFlags = HideFlags.HideInHierarchy; return(newGameObject); }
/// \cond protected override void Synchronize() { base.Synchronize(); ColoredCubesVolumeRenderer volumeRenderer = gameObject.GetComponent <ColoredCubesVolumeRenderer>(); if (volumeRenderer != null) { if (volumeRenderer.material != null) { // We compute surface normals using derivative operations in the fragment shader, but for some reason // these are backwards on Linux. We can correct for this in the shader by setting the multiplier below. #if UNITY_STANDALONE_LINUX && !UNITY_EDITOR float normalMultiplier = -1.0f; #else float normalMultiplier = 1.0f; #endif volumeRenderer.material.SetFloat("normalMultiplier", normalMultiplier); } } // Syncronize the mesh data. if (data != null) { // Syncronize the mesh data. if (data.volumeHandle.HasValue) { CubiquityDLL.UpdateVolume(data.volumeHandle.Value); if (CubiquityDLL.HasRootOctreeNode(data.volumeHandle.Value) == 1) { uint rootNodeHandle = CubiquityDLL.GetRootOctreeNode(data.volumeHandle.Value); if (rootOctreeNodeGameObject == null) { rootOctreeNodeGameObject = OctreeNode.CreateOctreeNode(rootNodeHandle, gameObject); } OctreeNode rootOctreeNode = rootOctreeNodeGameObject.GetComponent <OctreeNode>(); int nodeSyncsPerformed = rootOctreeNode.syncNode(maxNodesPerSync, gameObject); // If no node were syncronized then the mesh data is up to // date and we can set the flag to convey this to the user. isMeshSyncronized = (nodeSyncsPerformed == 0); } } } }
/// Gets the material weights of the specified position. /** * \param x The 'x' position of the voxel to get. * \param y The 'y' position of the voxel to get. * \param z The 'z' position of the voxel to get. * \return The material weights of the voxel. */ public MaterialSet GetVoxel(int x, int y, int z) { // The initialization can fail (bad filename, database locked, etc), so the volume handle could still be null. MaterialSet materialSet; if (volumeHandle.HasValue) { CubiquityDLL.GetVoxelMC(volumeHandle.Value, x, y, z, out materialSet); } else { materialSet = new MaterialSet(); } return(materialSet); }
public static GameObject CreateOctreeNode(uint nodeHandle, GameObject parentGameObject) { // Get node position from Cubiquity CuOctreeNode cuOctreeNode = CubiquityDLL.GetOctreeNode(nodeHandle); int xPos = cuOctreeNode.posX, yPos = cuOctreeNode.posY, zPos = cuOctreeNode.posZ; // Build a corresponding game object StringBuilder name = new StringBuilder("OctreeNode (" + xPos + ", " + yPos + ", " + zPos + ")"); GameObject newGameObject = new GameObject(name.ToString()); newGameObject.hideFlags = HideFlags.HideInHierarchy; // Use parent properties as appropriate newGameObject.transform.parent = parentGameObject.transform; newGameObject.layer = parentGameObject.layer; // It seems that setting the parent does not cause the object to move as Unity adjusts // the child transform to compensate (this can be seen when moving objects between parents // in the hierarchy view). Reset the local transform as shown here: http://goo.gl/k5n7M7 newGameObject.transform.localRotation = Quaternion.identity; newGameObject.transform.localPosition = Vector3.zero; newGameObject.transform.localScale = Vector3.one; // Attach an OctreeNode component OctreeNode octreeNode = newGameObject.AddComponent <OctreeNode>(); octreeNode.lowerCorner = new Vector3(xPos, yPos, zPos); // Does the parent game object have an octree node attached? OctreeNode parentOctreeNode = parentGameObject.GetComponent <OctreeNode>(); if (parentOctreeNode) { // Cubiquity gives us absolute positions for the Octree nodes, but for a hierarchy of // GameObjects we need relative positions. Obtain these by subtracting parent position. newGameObject.transform.localPosition = octreeNode.lowerCorner - parentOctreeNode.lowerCorner; } else { // If not then the parent must be the Volume GameObject and the one we are creating // must be the root of the Octree. In this case we can use the position directly. newGameObject.transform.localPosition = octreeNode.lowerCorner; } return(newGameObject); }
/// \endcond /// \cond public override void ShutdownCubiquityVolume() { if (volumeHandle.HasValue) { // We only save if we are in editor mode, not if we are playing. bool saveChanges = !Application.isPlaying; if (saveChanges) { CubiquityDLL.AcceptOverrideBlocks(volumeHandle.Value); } CubiquityDLL.DiscardOverrideBlocks(volumeHandle.Value); CubiquityDLL.DeleteColoredCubesVolume(volumeHandle.Value); volumeHandle = null; } }
/// Sets the color of the specified position. /** * \param x The 'x' position of the voxel to set. * \param y The 'y' position of the voxel to set. * \param z The 'z' position of the voxel to set. * \param quantizedColor The color the voxel should be set to. */ public String printData() { String toReturn = ""; QuantizedColor result = new QuantizedColor(); int lx = enclosingRegion.lowerCorner.x; int ux = enclosingRegion.upperCorner.x; int ly = enclosingRegion.lowerCorner.y; int uy = enclosingRegion.upperCorner.y; int lz = enclosingRegion.lowerCorner.z; int uz = enclosingRegion.upperCorner.z; Debug.Log("Dimensions on x: " + lx.ToString() + " to " + ux.ToString()); Debug.Log("Dimensions on z: " + lz.ToString() + " to " + uz.ToString()); Debug.Log("Dimensions on y: " + ly.ToString() + " to " + uy.ToString()); Debug.Log("volume Handle: " + volumeHandle.Value.ToString()); if (volumeHandle == null) { Debug.Log("null volume handle"); return(toReturn); } int i = 0; //for(int i = lx; i < ux; i++) //{ int j = 0; //for(int j = lz; j < uz; j++) //{ for (int k = ly; k < uy; k++) { CubiquityDLL.GetVoxel(volumeHandle.Value, i, k, j, out result); Debug.Log(" " + i + "," + j + "," + k + ": " + result.red + "|" + result.green + "|" + result.blue + "|" + result.alpha); } //toReturn = toReturn + "|"; //} //toReturn = toReturn + ";"; //} return(toReturn); }
/// \endcond /// \cond public override void ShutdownCubiquityVolume() { // Shutdown could get called multiple times. E.g by OnDisable() and then by OnDestroy(). if (volumeHandle.HasValue) { // We only save if we are in editor mode, not if we are playing. bool saveChanges = !Application.isPlaying; if (saveChanges) { CubiquityDLL.AcceptOverrideBlocksMC(volumeHandle.Value); } CubiquityDLL.DiscardOverrideBlocksMC(volumeHandle.Value); CubiquityDLL.DeleteTerrainVolume(volumeHandle.Value); volumeHandle = null; } }
/// \endcond /// \cond public override void ShutdownCubiquityVolume() { if (!IsVolumeHandleNull()) { // We only save if we are in editor mode, not if we are playing. bool saveChanges = (!Application.isPlaying) && (writePermissions == WritePermissions.ReadWrite); if (saveChanges) { CommitChanges(); } else { DiscardChanges(); } CubiquityDLL.DeleteVolume(volumeHandle.Value); volumeHandle = null; } }
public Mesh BuildMeshFromNodeHandleForColoredCubesVolume(uint nodeHandle) { // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f); // Required for the CubicVertex decoding process. // Create rendering and possible collision meshes. Mesh renderingMesh = new Mesh(); renderingMesh.hideFlags = HideFlags.DontSave; // Get the data from Cubiquity. int[] indices = CubiquityDLL.GetIndices(nodeHandle); ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle); // Create the arrays which we'll copy the data to. Vector3[] renderingVertices = new Vector3[cubiquityVertices.Length]; Color32[] renderingColors = new Color32[cubiquityVertices.Length]; for (int ct = 0; ct < cubiquityVertices.Length; ct++) { // Get the vertex data from Cubiquity. Vector3 position = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z); position -= offset; // Part of the CubicVertex decoding process. QuantizedColor color = cubiquityVertices[ct].color; // Copy it to the arrays. renderingVertices[ct] = position; renderingColors[ct] = (Color32)color; } // Assign vertex data to the meshes. renderingMesh.vertices = renderingVertices; renderingMesh.colors32 = renderingColors; renderingMesh.triangles = indices; // FIXME - Get proper bounds renderingMesh.bounds.SetMinMax(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(32.0f, 32.0f, 32.0f)); return(renderingMesh); }