It is currently Sat Aug 22, 2020 4:54 am


All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Some examples of adding and removing voxels?
PostPosted: Tue Dec 17, 2013 12:02 am 

Joined: Fri Dec 13, 2013 5:00 am
Posts: 11
Hi,

I can see in the C# script :
terrainVolume.data.SetVoxel(x, y, z, emptyMaterialSet);

How do I do this in Java?

I just want to add and remove voxels at the position of a GameObject like an Empty or a cube mesh.

I am trying to make a rigid body bullet for the Tank. When it hits the terrain I would like for it to add or remove voxels.

Sorry if this is a stupid request, but after this, I do not think I have many other questions. Everything else is already in cubiquity that I need.

This is a dream come true. I really had no idea it would be this easy to use your neat voxel engine.

Thanks :)


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Some examples of adding and removing voxels?
PostPosted: Tue Dec 17, 2013 9:19 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I'm not particulaly familier with JavaScript but I would expect it to be similar to the C# version. The class and function names will be the same but you may have to adjust the syntax slightly.

However, note that the example you gave it for the smooth terrain not the colored cubes terrain. The ColoredCubesTerrain works with 'QuantizedColor' rather than 'MaterialSet', and you can look at the 'ClickToDestroy.cs' script for an example of deleting voxels. It's basically:

Code:
myColoredCubesVolume.data.SetVoxel(xPos, yPos, zPos, new QuantizedColor(0,0,0,0));


voxi3d wrote:
This is a dream come true. I really had no idea it would be this easy to use your neat voxel engine.


That's what I like to hear - a lot of thought has gone into making the API easy to use :-)


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Some examples of adding and removing voxels?
PostPosted: Sun Dec 29, 2013 9:14 pm 

Joined: Fri Dec 13, 2013 5:00 am
Posts: 11
YAY! I got it to work. The line 57 needs to be this:

coloredCubesVolume.data.SetVoxel(resultX, resultY, resultZ, new QuantizedColor(0,0,0,0));

That will remove 1 voxel under the brush now.

Took us all afternoon to decipher that. I am taking all of my unity tutorials in C# for now on lol.

I am very happy now! :D

Have a nice day everyone. i am very excited to get to work :)

Here is what I have so far:
Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

using Cubiquity;

public class VoxelEdit : MonoBehaviour
{
   private ColoredCubesVolume coloredCubesVolume;
   
   // Bit of a hack - we want to detect mouse clicks rather than the mouse simply being down,
   // but we can't use OnMouseDown because the voxel terrain doesn't have a collider (the
   // individual pieces do, but not the parent). So we define a click as the mouse being down
   // but not being down on the previous frame. We'll fix this better in the future...
   private bool isMouseAlreadyDown = false;

   // 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 'VoxelEdit' script should be attached to a game object with a ColoredCubesVolume component");
      }
   }
   
   // Update is called once per frame
   void Update()
   {
      // Bail out if we're not attached to a terrain.
      if(coloredCubesVolume == null)
      {
         return;
      }
      
      // If the mouse btton is down and it was not down last frame
      // then we consider this a click, and do our destruction.
      if(Input.GetMouseButton(0))
      {
         if(!isMouseAlreadyDown)
         {
            // Build a ray based on the current mouse position
            Vector2 mousePos = Input.mousePosition;
            Ray ray = Camera.main.ScreenPointToRay(new Vector3(mousePos.x, mousePos.y, 0));
            Vector3 dir = ray.direction * 1000.0f; //The maximum distance our ray will be cast.
            
            
            // Perform the raycasting. If there's a hit the position will be stored in these ints.
            int resultX, resultY, resultZ;
            bool hit = ColoredCubesVolumePicking.PickFirstSolidVoxel(coloredCubesVolume, ray.origin.x, ray.origin.y, ray.origin.z, dir.x, dir.y, dir.z, out resultX, out resultY, out resultZ);
            
            // If we hit a solid voxel then create an explosion at this point.
            if(hit)
            {               
               coloredCubesVolume.data.SetVoxel(resultX, resultY, resultZ, new QuantizedColor(0,0,0,0));
            }
            
            // Set this flag so the click won't be processed again next frame.
            isMouseAlreadyDown = true;
         }
      }
      else
      {
         // Clear the flag while we wait for a click.
         isMouseAlreadyDown = false;
      }

      // mouse 2
      if(Input.GetMouseButton(1))
      {
         if(!isMouseAlreadyDown)
         {
            // Build a ray based on the current mouse position
            Vector2 mousePos = Input.mousePosition;
            Ray ray = Camera.main.ScreenPointToRay(new Vector3(mousePos.x, mousePos.y, 0));
            Vector3 dir = ray.direction * 1000.0f; //The maximum distance our ray will be cast.
            
            
            // Perform the raycasting. If there's a hit the position will be stored in these ints.
            int resultX, resultY, resultZ;
            bool hit = ColoredCubesVolumePicking.PickFirstSolidVoxel(coloredCubesVolume, ray.origin.x, ray.origin.y, ray.origin.z, dir.x, dir.y, dir.z, out resultX, out resultY, out resultZ);
            
            // If we hit a solid voxel then create an explosion at this point.
            if(hit)
            {               
               coloredCubesVolume.data.SetVoxel(resultX, resultY + 1, resultZ, new QuantizedColor(255,0,0,255));
            }
            
            // Set this flag so the click won't be processed again next frame.
            isMouseAlreadyDown = true;
         }
      }
      else
      {
         // Clear the flag while we wait for a click.
         isMouseAlreadyDown = false;
      }

   }



   
}


Mine only adds blocks on top of the one clicked. How does your voxel editor select which face the mouse is clicked on?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Some examples of adding and removing voxels?
PostPosted: Mon Dec 30, 2013 9:23 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Great, glad you are making progress :-)

voxi3d wrote:
Mine only adds blocks on top of the one clicked. How does your voxel editor select which face the mouse is clicked on?


Have a look at ColoredCubesVolumeInspector.cs. In particular we use 'PickLastEmptyVoxel' instead of 'PickFirstSolidVoxel'.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Some examples of adding and removing voxels?
PostPosted: Mon Dec 30, 2013 9:02 pm 

Joined: Fri Dec 13, 2013 5:00 am
Posts: 11
Ok I will definitely try this, thank you again!


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Some examples of adding and removing voxels?
PostPosted: Wed Jan 01, 2014 2:30 pm 

Joined: Fri Dec 13, 2013 5:00 am
Posts: 11
Wow! i forgot to include my script modifications.

Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

using Cubiquity;

public class VoxelEdit : MonoBehaviour
{
   private ColoredCubesVolume coloredCubesVolume;
   
   // Bit of a hack - we want to detect mouse clicks rather than the mouse simply being down,
   // but we can't use OnMouseDown because the voxel terrain doesn't have a collider (the
   // individual pieces do, but not the parent). So we define a click as the mouse being down
   // but not being down on the previous frame. We'll fix this better in the future...
   private bool isMouseAlreadyDown = false;
   
   // 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");
      }
   }
   
   // Update is called once per frame
   void Update()
   {
      // Bail out if we're not attached to a terrain.
      if(coloredCubesVolume == null)
      {
         return;
      }
      
      // If the mouse btton is down and it was not down last frame
      // then we consider this a click, and do our destruction.
      if(Input.GetMouseButton(0))
      {
         if(!isMouseAlreadyDown)
         {
            // Build a ray based on the current mouse position
            Vector2 mousePos = Input.mousePosition;
            Ray ray = Camera.main.ScreenPointToRay(new Vector3(mousePos.x, mousePos.y, 0));
            Vector3 dir = ray.direction * 1000.0f; //The maximum distance our ray will be cast.
            
            
            // Perform the raycasting. If there's a hit the position will be stored in these ints.
            int resultX, resultY, resultZ;
            bool hit = ColoredCubesVolumePicking.PickLastEmptyVoxel(coloredCubesVolume, ray.origin.x, ray.origin.y, ray.origin.z, dir.x, dir.y, dir.z, out resultX, out resultY, out resultZ);
            
            // If we hit a solid voxel then create an explosion at this point.
            if(hit)
            {               
               coloredCubesVolume.data.SetVoxel(resultX, resultY, resultZ, new QuantizedColor(0,0,0,255));
            }
            
            // Set this flag so the click won't be processed again next frame.
            isMouseAlreadyDown = true;
         }
      }
      else
      {
         // Clear the flag while we wait for a click.
         isMouseAlreadyDown = false;
      }
   }
   
   public bool IsSurfaceVoxel(int x, int y, int z)
   {
      QuantizedColor quantizedColor;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x, y, z);
      if(quantizedColor.alpha < 127) return false;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x + 1, y, z);
      if(quantizedColor.alpha < 127) return true;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x - 1, y, z);
      if(quantizedColor.alpha < 127) return true;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x, y + 1, z);
      if(quantizedColor.alpha < 127) return true;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x, y - 1, z);
      if(quantizedColor.alpha < 127) return true;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x, y, z + 1);
      if(quantizedColor.alpha < 127) return true;
      
      quantizedColor = coloredCubesVolume.data.GetVoxel(x, y, z - 1);
      if(quantizedColor.alpha < 127) return true;
      
      return false;
   }
   
   void DestroyVoxels(int xPos, int yPos, int zPos, int range)
   {
      // Initialise outside the loop, but we'll use it later.
      Vector3 pos = new Vector3(xPos, yPos, zPos);
      int rangeSquared = range * range;
      
      // Later on we will be deleting some voxels, but we'll also be looking at the neighbours of a voxel.
      // This interaction can have some unexpected results, so it is best to first make a list of voxels we
      // want to delete and then delete them later in a separate pass.
      List<Vector3i> voxelsToDelete = new List<Vector3i>();
      
      // Iterage over every voxel in a cubic region defined by the received position (the center) and
      // the range. It is quite possible that this will be hundreds or even thousands of voxels.
      for(int z = zPos - range; z < zPos + range; z++)
      {
         for(int y = yPos - range; y < yPos + range; y++)
         {
            for(int x = xPos - range; x < xPos + range; x++)
            {         
               // Compute the distance from the current voxel to the center of our explosion.
               int xDistance = x - xPos;
               int yDistance = y - yPos;
               int zDistance = z - zPos;
               
               // Working with squared distances avoids costly square root operations.
               int distSquared = xDistance * xDistance + yDistance * yDistance + zDistance * zDistance;
               
               // We're iterating over a cubic region, but we want our explosion to be spherical. Therefore
               // we only further consider voxels which are within the required range of our explosion center.
               // The corners of the cubic region we are iterating over will fail the following test.
               if(distSquared < rangeSquared)
               {   
                  // Get the current color of the voxel
                  QuantizedColor color = coloredCubesVolume.data.GetVoxel(x, y, z);            
                  
                  // Check the alpha to determine whether the voxel is visible.
                  if(color.alpha > 127)
                  {                     
                     Vector3i voxel = new Vector3i(x, y, z);
                     voxelsToDelete.Add(voxel);
                     
                     if(IsSurfaceVoxel(x, y, z))
                     {
                        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                        cube.AddComponent<Rigidbody>();
                        cube.AddComponent<FadeOutGameObject>();
                        cube.transform.position = new Vector3(x, y, z);
                        cube.transform.localScale = new Vector3(0.9f, 0.9f, 0.9f);
                        cube.renderer.material.color = (Color32)color;
                        
                        Vector3 explosionForce = cube.transform.position - pos;
                        
                        // These are basically random values found through experimentation.
                        // They just add a bit of twist as the cubes explode which looks nice
                        float xTorque = (x * 1436523.4f) % 56.0f;
                        float yTorque = (y * 56143.4f) % 43.0f;
                        float zTorque = (z * 22873.4f) % 38.0f;
                        
                        Vector3 up = new Vector3(0.0f, 2.0f, 0.0f);
                        
                        cube.rigidbody.AddTorque(xTorque, yTorque, zTorque);
                        cube.rigidbody.AddForce((explosionForce.normalized + up) * 100.0f);
                     }
                  }
               }
            }
         }
      }
      
      foreach (Vector3i voxel in voxelsToDelete) // Loop through List with foreach
      {
         coloredCubesVolume.data.SetVoxel(voxel.x, voxel.y, voxel.z, new QuantizedColor(0,0,0,0));
      }
   }
}


Just put this on the Color cube volume and you will be all set!


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net