Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Cubiquity - A fast and powerful voxel plugin for Unity3D

Discussion in 'Assets and Asset Store' started by DavidWilliams, Jun 2, 2013.

  1. Taalatharka

    Taalatharka

    Joined:
    Jun 11, 2013
    Posts:
    7
    Hello Mr. Williams,
    I've been looking around for terrain systems that would satisfy the need for malleable terrain in an RTSRPG designed for local co-op, and so far yours seems very promising.

    A few questions though, as I'm not a great coder and I figured I should ask before trying your system out and getting too attached to it (I'm sure I will):

    1) the multiplayer design calls for a lockstep synch model, so I figured we could gen the terrain once (for whoever starts the game) and then transfer it, and have each instance alter it in parallel; the question is, how deterministic do you think your system is? I expect I'll need to find my own physics solution, but I'm wondering how deterministic the terrain engine can be, especially when re-calculating the terrain after a deformation event.

    2) This may be a stupid question, but if I understand correctly, you could have multiple terrain plains (one large smoothed plain of 1m voxels, say, and several smaller ones of 20cm cubic voxels, for structures), and have multiple volumes present. How interactive can you make the individual volumes? Could I, say, have the 'structure' handle real-time interaction with the 'foundation', so if the 'foundation' were altered the 'structure' would react in real-time?

    3) I plan on putting in some realistic systems to restrict depth (stale air and whatnot) in most regions, but another stupid question: can Cubiquity support irregular intrusions into a plane, say if I wanted to have a cave system under a mountain (but only under the mountain), and not have the system generate (or even permit) chunks underground outside the mountain's perimeter? Or would I need to do something clever, like make that area a separate plane with different height and depth parameters?

    Thanks for taking the time to reply to our questions, it's very helpful to have so much information available about your tools and the topic in general :)
    Keep it up!
     
    Last edited: Jun 21, 2014
  2. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    I don't think you'll have any Cubiquity-specific problems here. If each client is working on the same volume data then I would expect the generated meshes to match.

    You might have to think a little about the process of transmitting the volumes though - be aware that a Cubiquity volume asset is actually just a thin wrapper around a '.vdb' file, so you'll need to transmit this as well. I don't think it's really a problem, but I haven't worked with Cubiquity in a network/multiplayer environment.

    Yes, this is correct.

    I think you can do this, but Cubiquity won't do it for you. If an explosion occurs on the ground near a building, then you would be responsible for deleting the nearby voxels in both the 'terrain' and 'building' volumes. Cubiquity will then automatically regenerate the corresponding mesh representation. You could also adjust the transform of the building to make it fall over, but it would be for you to decide how it should be transformed.

    We have made some cool demos with rigid bodies interacting with the volumes, but we have never tried making the volumes themselves into rigid bodies (eg. allowing volumes to be moved around the scene in response to physics/collisions). This would be a very interesting thing to play with but might not work out-of-the-box, and I'm sure the built in Unity terrain would not be able to do this anyway.

    I'm not entirely clear on your question. In general Cubiquity doesn't handle the generation of the terrain (though there is an example) - it just gives you a 3D grid of voxels which you can write into. So in your terrain generator you can implement whatever restrictions you wish.
     
  3. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Hi David,

    I'm trying to import a slab.vox file from Magica Voxel but am getting "Unrecognised input format" from the ConvertToVDB.exe file. I've grabbed the latest version from bitbucket but am still getting this error.

    It's also the latest version of Magica so it could be an issue from their side as well.
     
  4. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    I just tested a model from MagicaVoxel 0.93 when running ConvertToVDB.exe on Windows 7 and it seemed to work ok. Which exact version and platform are you using? If you are on OS X I will need to update the binaries I think. Maybe you can send me the .vox file?

    Edit: Hang on, a 'slab' .vox? I think that's not the native Magica Voxel format, but one of the export options for Ken Silverman's engine/tools? Can you save a a normal Magica .vox file instead?
     
  5. Taalatharka

    Taalatharka

    Joined:
    Jun 11, 2013
    Posts:
    7
    Thanks for replying so quickly!
    I've been reading up more and thinking about voxel terrain more, and realized that my question is a complete non-issue; basically, I was asking if the 3D voxel structure could be very irregularly shaped, on all facets (in this case, the 'underside').
    What I really should have asked, is how it handles empty coordinates, or if it even tries to do so, but I'm guessing it just doesn't, as that's not really it's job.

    So the question has been answered.
    If I understand correctly, based on the origin of the scene's 3D space, you can depict a 3D volume of Voxels (of most any shape or size) of varying composition.
    I could, for example, have it generate a thin layer of voxels (say, 5 to 15 deep) in a flat plane, and then have it expand into a huge vertical clump somewhere, both up and down; it need not conform to a plane at all, however (the floating islands demo, yes?).

    Very interesting, I like it.
     
  6. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Hi David,

    Ahh, yes you are correct. It's my first time with MagicaVoxel and I didn't release there were other vox files hiding in there!
    Used the correct file and it all worked fine.

    Cheers!
     
  7. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Yes, Cubiquity basically just provides you with a 3D array, and it's up to you what you write into each element. In the case of the ColoredCubesVolume each element of the array is a color, and in the case of the TerrainVolume each element of the array is a combination of materials. Because it is a 3D array (rather than a 2D heightmap) you have complete freedom to create caves, overhangs, layers, floating islands, etc.
     
  8. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    G'day David,

    I'm working on a memory leak in Liquid Voxels but I'm starting to suspect it may be in Cubiquity somewhere. There's a strong possibility I'm wrong as I've never tried fixing a memory leak before :)

    What I did was restart Unity then set up a scene with my simulator using the "Render In Terrain" plugin. Then I ran it for a while with task manager to see what the memory did, it slowly climbed to over 200mb, this continues on until an out of memory error occurs.

    Next I changed the render plugin to a custom mesh renderer that builds a it's own mesh instead of asking cubiquity to draw the water. Restarted unity and ran the same scene. The memory tops out at around 170-180Mb and stops growing.

    I'm thinking this means it's either my code that asks cubiquity to update (and it very well could be!) or Cubiquity.
    I don't have Unity pro, so no awesome profiler for me, but I do have a unity profiler asset called Benchy, so I'll be doing some profiling work tonight.

    Video of above results:
     
  9. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    @Ellandar - there are indeed some issues here, both with the memory consumption and also with memory not being returned as quickly as it could be. Liquid Voxels will be pushing this quite hard because you are updatig the mesh so frequently, and this will cause lots of allocations of mesh instances.

    It's not something I'm too worried about though - it needs to be fixed but there are standard techniques (such as pooling) which can address this problem, and which should be used in later versions of Cubiquity.
     
  10. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Wonderful, I'll cross that bug off my list then. I like it when problems solve themselves!

    That frees me up to fix the big performance problem you found in my asset. :)

    - Ell
     
  11. Paniku

    Paniku

    Joined:
    Apr 11, 2013
    Posts:
    24
    Hi, just curious: Despite the component being called "Terrain Volume", it seems like it would work fine for any voxel-related object (even if an enemy was made of voxels, for example). Is this correct?
     
    Last edited: Jun 26, 2014
  12. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Yes, you can indeed use it for other purposes if you wish. However, it is only really appropriate for modeling smoothly changing shapes and so it is difficult (but not impossible) to use it for buildings. We called it the 'TerrainVolume' because this is the most natural application, and we didn't want people thinking it was intended to be used just like Minecraft.

    The ColoredCubesVolume is a little more flexible and can be used for any kind of environment, including buildings. Neither volume type is intended for characters though as they can't be animated beyond adding/removing voxels and transforming the volume as a whole (e.g. no skeletal animation).
     
  13. Paniku

    Paniku

    Joined:
    Apr 11, 2013
    Posts:
    24
    Thanks, I've been playing around with the CCV and I've run into an issue with having multiple instances of a voxel object. The voxel data is linked (which I don't want), and duplicating the voxel asset (which doesn't seem feasible at runtime) causes a "database is locked" runtime error. Any suggestions regarding what I should do here?
     
  14. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Hi Paniku,

    If you are creating your objects in code, I suggest doing the following:
    1. Create a new GameObject.
    2. Create a new volume (David has supplied some good methods in his core code and examples on how to do this) and attach it to the gameobject.
    3. Copy the volume data from your existing model into the new volume.

    Alternatively there is a method in David's code that will create the whole new gameobject with new volume attached. I can't recall the name or the class as I'm currently at work.
    Once you have the new object you can then copy the volume data into the object.

    You now have a new object with a new voxel database backing it.

    If you are talking about creating characters that walk around the world, I would suggest you create the object in a 3d art package like blender (or buy a character), and then convert it to a cubic looking art style using something like: O2V to make it look like a voxel object.

    That way it fits in your game world style, and you get all the power of unities mechanim, animation and character controller systems.


    - Ell
     
  15. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    I must admit that I didn't give much consideration to having multiple instances all sharing the same voxel data. I expected that people would use a single volume to represent the whole environment (e.g. a whole city or a whole landscape), or that perhaps multiple volumes would be used to represent multiple planets (because they may transform relative to eachother).

    However, I'm sure the current situation can be improved and supporting better duplication/sharing/instancing of volumes is what I am primarily working on at the moment. I'm not sure how far it will go because it doen't seem possible to intercept Unity's 'duplicate' command (which we'd need to do to ensure a .vdb gets duplicated when a volume asset get duplicated) but I hope that some enhancements can be made.

    Can you elaborate on why you want to work with multiple instances? For example, if you are trying to place multiple copies of a building across a landscape then could you write them directly into the volume data instead?

    In the mean time you can use the approaches described by Ellandar as an alternative solution.
     
  16. Krooq

    Krooq

    Joined:
    Jan 30, 2013
    Posts:
    194
    First off, this is really really fantastic, I am amazed by the fantastic work David. And the free version for non commercial use is brilliant.
    My question is in regards to the serializing of vdb files and the Voxel Databases

    Suppose I want to procedurally generate a cubic type terrain during runtime,
    then save/serialize this vdb file to a location that I choose,
    so that I can reload this vdb during runtime

    How would I go about this?

    Additionally do you think at some point the ability to add a texture to each cubic voxel will be implemented? I'm sure this has been mentioned before but i couldnt find it.

    Thanks Gavin
     
    Last edited: Jun 29, 2014
  17. duke

    duke

    Joined:
    Jan 10, 2007
    Posts:
    763
    When are the LOD capabilities being added?
     
  18. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Ok, I'm back from vacation - time to crunch some more voxels.

    Thanks! These kind of positive comments are really inspiring :)

    The underlying Cubiquity library doesn't really care where it gets it's data from, but the Cubiquity for Unity3D wrapper constrains the .vdb to be within the Streaming Assets folder so that it will be included when you do a build. These restrictions are intended to make it harder for users to accidentally break the system by linking to a file which then doesn't get included.

    So the current answer is that you can't save the .vdb to arbitrary locations of your choosing, but I can also see that this may be desirable in certain situations. For example, perhaps the player is building/editing a map from within the game and you want this to persist across multiple play sessions. Makes a lot of sense actually, but so far I was focused on maps which were provided in advance by the developer.

    I'll keep this scenario in mind as I work on the .vdb and volume asset system over the next couple of weeks.

    There are no short term plans for this but it is a popular request. I think it is more likely that the TerrainVolume would be enhanced to better support sharp edges/corners (e.g. via dual contouring) as this would also give you what you need, but again that's not a high priority at the moment.

    I hope to get the next Cubiquity release out by the end of this month but it will mostly be a bug fix release. After that I want to focus on performance and scalability to support much larger volumes. LOD may well form a part of this but I suspect there are other easier and/or more important enhancements to be made first.

    So if you actually want larger volumes then I think it will come relatively soon (next few months) but if you specifically want LOD then there's not really a set date for this.
     
  19. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Hi David,

    I have a design question. It's just me being curious as to what the thought process is as opposed to that I don't like the behaviour (I'm pondering similar questions myself right now).

    When I set a voxel that is out of bounds of a cubiquity region, there is no feedback as to the fact that it failed. I also notice in the code for GetVoxel you wrote a note to yourself that said "Should maybe throw instead.".

    I'm dealing with a similar problem but the actual in bounds check is expensive, so I'm considering providing no response at all on failure.
    What are your thoughts on this type of feedback? I'm leaning on the side of "a quiet plugin is a good plugin" but silently failing also has it's drawbacks during debugging.

    Ell
     
  20. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Yes, I'm still undecided on this. There's actually several levels to the question from Cubiquity point of view:
    • Should the native code library perform bounds checks? I'm not sure what the overhead is but it would be possible to provide two versions of the accessors (one with bounds checks and one without).
    • If it does do a check, then should the native code library return an error or silently discard the out of bounds voxel?
    • Should the C# wrapper also perform the check or rely on the underlying library doing it? Checking in the wrapper avoids wasted calls across the managed/native boundary and can probably give more meaningful exceptions, but could be unnecessary duplication.
    But I think I've mentioned that I'd eventually like to remove the concept of regions anyway, so that a user can read/write to any voxel at any time with chunks being created on-the-fly. At this point I guess the issue goes away anyway which is why I've not worried about it too much..

    In your scenario are you concerned with the user accessing outside of your prescribed region, or with your code accessing outside of the underlying voxel engine? Because I guess the latter will happen a lot due to the nature of fluid simulation. If you or I did throw an exception then could the user do anything with it or would they just have to silence it anyway? Could/should they have done anything to prevent the out-of-bounds access? If not then I guess the exception is not useful?
     
  21. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Mainly the first one, users requesting liquid to do things (add/remove) outside of a region. I do provide methods to determine if a world location is in a region or not; I might just create a debug mode that does warn that can be turned off.

    The latter only occurs if my regions are in a location that has no voxels under it; that is a case I'm trying to work through; I'm thinking of doing some checks when moving regions around and changing the region color when it's invalid.

    That is a good philosophy "Don't throw or error if the user couldn't do anything to avoid it in the first place".
     
  22. axelz58

    axelz58

    Joined:
    Apr 27, 2013
    Posts:
    17
    will there be some sort of slice/blend or set height tool?
     
  23. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Eventually I think there will be (useful for plateaus, cliffs, etc), but I think support for importing external heightmaps will come first. Then you will be able to create your maps in an external tool.
     
  24. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Hi all,

    I'm thinking of upgrading to Unity 4.3 which would then become a minimum requirement for the next version of Cubiquity. Currently I'm using 4.2 but it seems that not many other people are:



    So, are then any active (and ideally paying) users of Cubiquity who are still using Unity 4.2 and who are reluctant to upgrade?
     
  25. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Just to follow up on this, we have indeed now moved to Unity 4.3 which is now the minumum tested version for Cubiquity. It might still work on 4.2 but we can't make any guarentees about this. It has fixed some minor namespace-related bugs, meaning the volume data classes (VolumeData, TerrainVolumeData, and ColoredCubesVolumeData) have now been moved into the Cubiquity namespace where they belong.
     
  26. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Hi Gavin,

    This has now been resolved in the development version of Cubiquity. Both the 'CreateFromVoxelDatabase()' and 'CreateEmptyVolumeData()' functions can now accept a full path the the .vdb file, so that it can exist outside of the streaming assets folder. Please see the API docs in the code for details.

    Note that the development version of Cubiquity currently only has the native code library built for Windows, so if you want to use the development version on OS X then let me know and I'll update the buld of that too. Or you can wait for the next official release of course.
     
  27. duke

    duke

    Joined:
    Jan 10, 2007
    Posts:
    763
    My question about the LOD feature was to do with playing Planet Explorers and being impressed with the draw distance (compared to say, minecraft) and seeing if cubiquity could do something similar. It didn't perform too well at 1024x1024x64, so i looked around and found a few blog posts on your site about voxel LOD'ing.
     
  28. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Yes, we do indeed have a LOD algorithm but it's currently only implemented in our prototype (written using Gameplay3D rather than Unity):


    I think that we will expose this to Unity as part of supporting larger volumes, but it serves mostly to reduce the GPU load and actually I suspect this won't be the first bottleneck we hit. CPU and memory are probably the the first targets to optimize but some profiling will be needed to know for sure. I'm not too worried though - I'm aware of a lot of low-hanging fruit which should make a big difference.
     
  29. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Hi David,

    I'm not sure if we spoke about this at some point, but a method to update a number of voxels at once would be really handy, if you were looking for things to implement ;)

    Being able to supply an array of voxels to Cubiquity to update would potentially save on quite a lot of mesh rebuilds; and at the very least a tonn of calls.
    I do understand that my use-case of Cubiquity is very specific so I wouldn't put a huge amount of weight into the request.

    Oh, and grats on the 4.3 move; I've been using it and it's been very stable so far.

    Also FYI; 4.5 fixes the problem where you can't overload methods with default values in classes within your own namespace. That broke a couple of my classes and took a heap of time to work out why things weren't working.

    - Ell
     
  30. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Yes, I agree this is still desirable. We do have a task logged for it but no particular schedule. Actually the interface isn't quite clear to me - what if you only want to update some of the voxels in the region and leave the rest with their current value? Do you want to have to get all voxels in the regions first, or perhaps you are keeping track of them anyway?

    Actually this shouldn't be affected, mesh rebuilding is deferred until some later point once all your voxel changes have been made.

    Yes, it would save on calls across the managed/native boundary. I don't know how expensive these are - some profiling is required.

    Good! The duplication issues are quite complex and I'm not sure I've settled on the final solution. But it's much better now and will warn the user if the duplicate something they shouldn't. I'm currently writing docs to try and explain the situation.
     
  31. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    I tend to only want to update a subset of voxels I've already identified need updating. Something like:
    Code (CSharp):
    1. Vector3i[] voxelsToSet = all the locations to update.
    2. MaterialSet materialToSet[] = material in each location (or just a single material?)
    3. terrainVolume.data.SetVoxel(voxelsToSet, materialToSet[]);
    similar for cubic:
    Code (CSharp):
    1. Vector3i[] voxelsToSet = all the locations to update.
    2. QuantizedColor colorsToSet = array of colors to set, or even just a single color.
    3. coloredCubesVolume.data.SetVoxel(voxelsToSet, colorsToSet);
    Having written that, I'm starting to wonder how truly helpful this would be.
    Basically if the engine delays mesh updates to late in the frame (like you mention), or later, then my perceived need for this drops a lot.
    Really it would just be a convenience method, as either my code or your code still has to iterate through the array, so I'm thinking my need for it dropped a little :)

    This invalidates my underlying assumption I made when proposing bulk update, perhaps in the future I should be posting questions to clarify my assumptions before posting possible solutions without being clear ;)

    This is probably the only area, and to be honest, I'm not 100% sure if there were significant gains to be had here. We are really just talking about which party in the equation iterates an array, so I'm actually thinking your time is probably best spent elsewhere until you are looking for extra things to do.
     
    Last edited: Jul 16, 2014
  32. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    @Ellandar - No problem - I still think this feature is desirable (for convenience if nothing else) but I haven't worked out how important it is. Also, you talk about setting voxels but you don't talk about getting them... do you query the state of the Cubiquity voxels every frame? I can imagine you already know the state as you are maintaining your own separate array, but what if the user is modifying the state of the volume while the simulation is taking place?
     
  33. Ellandar

    Ellandar

    Joined:
    Jan 5, 2013
    Posts:
    207
    Just as I was adding regions I removed the local copy of the voxel world in my 3d arrays.
    I still sample the world but I no longer scan the terrain and store a local copy, as it was adding seconds (sometimes minutes) to the initial load.

    I request voxels from the terrain every time a block of water needs to move into a non-water voxel. Basically it's just a "is this solid or empty" check at the moment. The query is always a single voxel and I always know the location I'm asking for before I need to talk to Cubiquity, so mass "can I have an array of voxels please" query isn't something I need at the moment. Cubiquity is returning voxels really fast, it's certainly not a bottleneck at the moment.

    Yup, using this method it still can react to world changes. Although I should make that part of my pre-release checks (throwing an explosion or two around) I think, as I haven't tested that for a while.
     
  34. mrleerman

    mrleerman

    Joined:
    Jul 15, 2014
    Posts:
    3
    David

    Excellent work sir. I have been playing around with colored cubes and have some feedback. (Please excuse the wall of text)

    1) Please add me to the list of people asking very nicely for ColoredCube texture support to be added. Like several others, I'm looking to do Minecraft style building on top of a TerrainVolume and it'd be great if the two terrains at least sort of blended together. (Also I saw your screenshot of normal mapped ColoredCubes and sure would like to do cool texture-y things like that)

    2) I want to enable finer detailed building so I plan to use small ColoredCube voxels. I poked around the API but couldn't find a way to specify voxel size when creating a ColoredCubesVolume or a ColoredCubesVolumeData so I assume the intended solution is to scale the ColoredCubesVolume. However, this seems to have issues.

    I used the GameObject->Create Other->Colored Cubes Volume menu sequence to place two ColoredCubeVolumes into a test scene. I peeked at your menu code so I know these are 256 voxels wide and deep so I gave the second volume a translation of 256, 0, 0 to make one continuous slab. I then gave the second volume a scale of 0.5, 0.5, 0.5 in an attempt to make its voxels half the size of the first volume's. Considering the volumes have a default 8 voxel floor on them, I turned 8 more of the second volume's voxels on in a vertical column which should make the floor + column's height equivalent to the unscaled volume's floor's height. I started game mode, flew over to the adjacent corner and saw this:

    upload_2014-7-19_10-26-16.png

    Two very strange things seem to be happening. First, the actual voxel rendering of the two volumes seems to be stillining up. That is, the scaled volume's voxels are rendering as though they are not scaled causing some of them to have color shifts mid-way through them (see furthest right green voxel in second picture below).

    upload_2014-7-19_10-29-6.png

    While this is sort of a neat effect, it is definitely not what I expected. Maybe this "bug" could become a "feature" with a checkbox in the ColoredCubesVolumeRenderer inspector panel? :O)

    The last thing that seems to be wrong here is that the bottoms (and thus the unscaled floor and scaled green column) of the two volumes don't actually align. I was convinced this was a trick of the perspective camera at first, but the more I flew around to look at it the more certain I am that the volumes don't actually align.

    Is this offset intended behaviour? It's a little disconcerting because I was intending to place a TerrainVolume and a scaled ColoredCubesVolume at the origin to mix the two approaches. It would be problematic if the scaled volumes and non-scaled volumes don't align.

    3) This has gotten absurdly long, so the last bit I want to mention is slanted ColoredCubes. Again, I am intending to juxtapose a ColoredCubeVolume against a TerrainVolume for structure building and I would like them to at least sort of blend together. I think "partial" ColoredCubes would go along way to making this look better. Think slants between parallel faces, but also so far as internal corners within the cube. Here's a random, bad picture of a cube with a corner in it (I was thinking more "sloped" walls going down to the internal corner):



    If that makes sense? Any chance support for these could make it in at some point?

    Again, excellent work sir and thanks so much for opening this up to the public.
     
    Last edited: Jul 20, 2014
  35. Lijax

    Lijax

    Joined:
    Jun 19, 2014
    Posts:
    4
    Hey David, I'm having trouble comparing material sets. Is there possibly a method to check if the material set represents a empty voxel. I'm trying to see if an area around a given object contains a certain amount of voxels. Thanks in advance.
     
  36. tobischw

    tobischw

    Joined:
    Aug 28, 2012
    Posts:
    21
    Are there any editors that can export to the vdb format? I tried to make a map using voxed and export it as .vxl and then convert it to .vdb, but the Converter creates an invalid .vdb file, no matter what maps I try.
     
  37. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    A sudden burst of interest - excellent stuff! Let's take a look...

    Ok, thanks, it's certainly a popular request. It's not going to happen short term though - after the next release I want to focus on significantly increasing the size of the volumes, so I hope that by using smaller voxels you can get similar detail to what would be possible with larger textured voxels. We'll have to see how this works out.

    Yes, this is correct.

    I think this issue is probably fixed in the latest develop version of Cubiquity (at least I didn't manage to reproduce it). There was some refactoring of this code as I added the normal mapping to the voxels so it's quite possible other stuff got fixed. You can try the Git version, or wait for the next release which I'm still hoping to do by the end of the month.

    Yes, this is expected. The issue is that each cube is centered on the corresponding position, rather than being at one of the corners. That is, voxel (0,0,0) is centered on position (0,0,0) and extend from (-0.5, -0.5 -0.5) to (0.5, 0.5, 0.5).

    Is it really a problem if they don't align? The Terrain volume is a smooth density field and the 'voxel edges' are not really visible, so it's not really clear why alignment is beneficial (I'm playing Devil's advocate a bit here ;-) ). I can imagine it might help with building operation, but even then a user is only likely to modify one volume at a time. Can you describe a use-case where it matters?

    Unfortunately this isn't quite clear to me. Are you wishing to have a different orientation between your ColoredCubes and Terrain volumes? That would be possible. But I think you mean you would like to somehow cut edges and corners of the cube so that they fit better with the terrain? Can you not just allow the cubes to poke through the terrain, or will this cause problems somehow? I think I'm not quite understanding your problem.

    This is a good question - actually the concept of an 'empty' voxel is a little ambiguous in the TerrainVolume. You have access to the MaterialSet and if the sum of all the materials for a given voxel is zero then you can definitely consider that voxel as empty. However, if the sum of values if greater than zero but still less than the required threshold (127) then the voxel isn't exactly 'empty' but it's also not visible.

    For your purposes the best option might be to count the voxel as empty if the sum of it's weights is less than 127 (it might be handy if we provided a function for this). Alternatively, rather than counting the number of empty voxels in your region, perhaps you could just compute the total amount of 'material' by summing all the weights in all the relevant voxels. You'll have to think what makes sense for your scenario.

    There are at least some issues with .vxl import which have been fixed in the latest version (not yet released). Can you try the latest version to see if it works for you? You can get the latest version from Git here:

    https://bitbucket.org/volumesoffun/cubiquity-for-unity3d

    Note that the Git version only works on Windows at this moment. If you need to test on MacOS then let me know and I'll upload new binaries. If you don't know how to use Git then let me know and I'll show how to download a source zip file.

    Oh, and there are no direct .vdb editors. It's a Cubiquity-specific format which is why we provide the converters. If the problem persists then maybe you can upload a sample .vxl file so I can reproduce the problem?
     
  38. tobischw

    tobischw

    Joined:
    Aug 28, 2012
    Posts:
    21
    Hi,

    Thanks for the quick and friendly response.

    Yes, I would really appreciate OS X binaries. Maybe the reason the converter didn't work was because I'm using Bootcamp for my Mac. I will try the new version on Bootcamp and see if it works this time.

    And yes, I realize .vdb files are Cubiquity specific, but I'd be awesome if you could release specifications on how the format is structured so that I could integrate it in my own editor.

    I'll attach an example vxl plus a screenshot after I get off work.

    EDIT: Here we go.

    Here's the .vxl file I'm trying to convert: http://aloha.pk/files/aos/maps/hallway.vxl

    And here's the cmd output after I try to convert the map to vdb:


    It does however create a .vdb file, but when I'm trying to import it in Unity, I get a SQLlite parse error. I mean, it does recognize it as a .vxl file.

    I don't think I'm using the wrong args or syntax. I really don't know why it won't convert - does the Unity project have to be running in the background? I didn't open cubetest yet in Unity, so it might not have copied the required libs.

    Thanks for the help.
     
    Last edited: Jul 20, 2014
  39. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    @epic2011 - Ah, ok, I remember now. There was actually a problem with the .vxl import in the released version of Cubiquity, but this has been resolved in the latest version (available from the Git repo). However, the code in the Git repo is dependant upon the latest version of the Cubiquity native code libraries. The Widows versions of these libraris are up to date, but the OS X versions are not (basically because I develop on Windows). I'll try to get the OS X binaries compiled and updated in the next couple of days, but as you mentioned Bootcamp I guess you may have Windows on your machine as well?

    In the mean time, here is the converted .vdb file: https://drive.google.com/file/d/0B7b4UnjhhIiEZEV5X1QxQkZkMlU/edit?usp=sharing

    I believe it should be possible to use it with the released version of Cubiquity, though again I only tested with the development version.

    The format isn't really designed for external use - it's an SQLite database which holds the blocks of voxels and some other info. As it's SQLite format I couldn't actually tell you how it's laid out. However, we are working on the C interface for Cubqiuity, so in principle it would be possible for you to load this as a plugin in your editor and call the Cubiquity functions to write out the voxel data.
     
  40. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
  41. Lijax

    Lijax

    Joined:
    Jun 19, 2014
    Posts:
    4
    Hi David, thank you for help last time. I appreciate it, but alas, it did not work correctly. Maybe if I explain the current scenario of our game you might be able to help more specifically. We have a terrain volume. Inside the terrain volume is an object with a known radius, and position. Is there a way we can iterate through the voxels around it to see if it is touching any terrain, or to know if a certain percentage of it is not touching any voxels. This is the current method I was attempting to use with your previous advice:

    void checkObject(){
    int total = 0;
    int empty = 0;
    int weight = 0;
    int xPos = (int)Artifact.transform.position.x;
    int yPos = (int)Artifact.transform.position.y;
    int zPos = (int)Artifact.transform.position.z;
    int range = (int) (Artifact.renderer.bounds.max.x - Artifact.renderer.bounds.min.x) / 2;
    int rangeSquared = range * range;
    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.
    int off = Random.Range(-5,0);
    if(distSquared < rangeSquared+off)
    {
    total++;
    //Debug.Log(terrainVolume.data.GetVoxel(x, y, z).weights[1]);
    for (uint i = 0; i < 8; i++){
    Debug.Log (terrainVolume.data.GetVoxel(x, y, z).weights);
    weight += terrainVolume.data.GetVoxel(x, y, z).weights;
    }
    if (weight < 127) {
    empty++;
    }
    }
    }
    }
    }
    }

    Thank you in advance.
     
    Last edited: Jul 23, 2014
  42. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    @Lijax - I notice a couple of things in you code which may be a problem:

    1. You have a loop with variable 'i' but you're not actually using 'i' inside the loop. I guess this was just a typo and that

    Code (csharp):
    1. weight += terrainVolume.data.GetVoxel(x, y, z).weights;
    Should have been:

    Code (csharp):
    1. weight += terrainVolume.data.GetVoxel(x, y, z).weights[i];
    2. Watch out for transformations, as 'Artifact.transform.position' will be in world space (I think?) whereas the Get/SetVoxel() functions are in 'volume space' (relative to the lower corner of the volume). Of course this isn't an issue if you do not have a transformation applied to your volume.

    Anyway, I think you were close but I've made a modified version of 'ClickToCarveTerrainVolume' which could the number of solid/empty voxels before and after the terrain is destroyed:
    I have to admit that working with MaterialSets is a little complex (and even working with regular density fields can be confusing). For testing purposes you may want to simplify your volume, e.g. by only using the first wieght (a single material) or by only setting voxels to be 'fully' solid or empty. This looks ugly but is easier to understand.
     
  43. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    Hello! i love that you have put this out for free when doing it for non commercial use! Im not a programmer and i find it quite hard to penetrate the API and how to use it. What i have learnd about scripting in unity is pretty much brute force and trail and error. I have managed to understand most tools by just getting an introduction and then trail and error!

    Could you point me in the right direction on how to perfrom runtime edeting of a terrainVolume? im not asking for a step by step tutorial, but what classes should i use, what are the most important parts of these and what do i change to manipulate the terrain? for example.....say that i wanted to be able to create a hill at runtime? how would i go about and do this? and would i be able to let the player change the size of the brush and the material at run time? where do i start?

    keep up the awesome (and free) work :)
     
  44. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    The best advice is to start simple, and to probably begin with ColoredCubesVolume rather than TerrainVolume (the interface is almost the same, but colored cube voxels are easier to understand).

    You can create a volume completely from code, but again it's probably easier to create a blank volume (with just a floor) in the editor and then attempt to edit this in game. Create a new component, implement the Start() function to get the data and set some of the voxels to empty, add your component to your volume, and press play.

    Be sure to check the docs, but the basic idea is that every Volume has a 'data' member which provide access to the underlying VolumeData. You can then call GetVoxel() and SetVoxel() on this volume data to modify it.

    After you've got the hang of getting and setting voxels you can try using picking to make a marker follow your mouse as you move it over the terrain, and then try using the marker position for any operations you perform.

    For examples you can look at the 'ClickToDestroy' and 'ClickToCarveTerrainVolume' scripts for colored cubes and terrain volumes respectively. Also the Unity edit-mode functionality in built on the standard Cubiquity API (at least in the case of ColoredCubesVolume) so you can also look at ColoredCubesVolumeInspector and TerrainVolumeInspector in the editor folder.

    Be aware that adding/removing voxels is quite straightforward, but sculpting/painting is a little more complex. There isn't really a clean API exposed for that yet, so again you would have to look at TerrainVolumeInspector which basically calls the 'magic' TerrainVolumeEditor functions.
     
  45. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    @saarwii - I was notified of a couple of responses but now I don't see them... I guess you solved the issues by yourself? But just in case, most of the code from the editor should indeed work in-game as well. There may be some rough edges but in principle it should work. As for the strange behaviour you saw, you will need to constrain the inputs (size, opacity, etc) to the same values which the editor allows.
     
  46. axelz58

    axelz58

    Joined:
    Apr 27, 2013
    Posts:
    17
    would it be possible to generate a terrain with no mesh on the bottom part in order to reduce poly count?
     
  47. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    i asked some questions and then i solved them...i found the method i needed....TerrainVolumeEditor.SculptTerrainVolume(); .... im now in the process of figuring our what all the things actually do...How does the different floats interact.....

    i figured out that amount = opacity and if it goes over 1 you get weird results.
    Radius = brushOuterRadius and should not go over 10...
    but im still looking at how brushInnerRadius affects the results and how centerY comes in to play.. i guess center y changes depending on how high the hills gets
     
  48. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    No, I'm afraid this is not possible at the moment. It *might* happen in the future as we move to large/infinite volumes but I'm not quite clear on that yet.
     
  49. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    The inner and outer radius can be used to control the falloff of the brush. At the center of the brush the maximum change is applied to the terrain, and this maximum change is applied all the way out the the inner radius. Then the amount of change decreases in a linear fashion until outer radius is reached, and outside that there is no change at all. You can see this falloff in effect in this video (jump to 2:35):


    If you look at the predefined brushes, the one on the right has a sharp falloff (inner and outer radius are the same) while the one on the left has a gentle falloff (inner radius is much les than outer radius).

    The center x/y/z control where the sculpting is applied. The Y value is not special because a voxel terrain exists in all three dimensions, unlike a normal heightmap.
     
  50. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    i got a bit further with it, i took alot of code from the inspector script...i also got a brush to follow the mouse at runtime :) The only problem i have there is that the control is inverted...if move the mouse down on the screen, the blue brush moves up...left and right work but not up and down....

    Can i make custom brushes? like a square brush or anything like that?