Telarin
There are a few tasks that I need to accomplish in Unity, and after looking through the cs files for Voxel Farm, I don't see any methods exposed to do them. I'm hoping I am just missing them, and you can point them out to me. If not, maybe provide some pointers on how modify the Plugin to do the job.

1) After calling SetBlockLineOfSight, I need to find out what the material is of the voxel at the selected hit location to determine exactly what will happen when the player interacts with it. I also need to know the position of that voxel relative to the player so I can determine if they are even close enough to interact with it.

2) Given a world x, z position, how can I determine the height of the terrain at that location (original height generated from the Voxel Studio package, not considering any user changes).

3) How can I determine the material at an arbitrary x, y, z location?
0 0
voxelfarmtorres
These tasks are not exposed to the C# side yet, but the information is easily accessible from the C++ side, that is, inside the DLL.

1) Please look into this post by another user: https://forums.voxelfarm.com/post/get-voxel-data-from-raycast-8497149?pid=1295589448

2) You can call the getHeight() method to the SimplexWorld object. The instance of this object is located in the DLL code inside the VoxelFarm::Client::CVoxelFarmBundle::CVoxelFarmBundleImpl class (VoxelFarmInitBundle.cpp)

3) This depends on whether you want procedurally generated materials to be included or not. There are two main sources of voxel data: procedural and user-generated. Procedural voxel data lives briefly, it is discarded after a visual representation of the voxels is computed. User voxel data, on the other hand, persists as originally created. If you want to sample both procedural and user voxels at an arbitrary xyz location you must:

1- Compute the voxel coordinates for the x,y,z. For the voxel coordinates, you need to know which cell contains the voxel and then the xyz index of the voxel within the cell. The cell ID can be computed as follows:

double scale = (1 << lod)*CELL_SIZE; // here lod is which level of detail you would like to sample, use LOD_0 constant for highest detail
int xc = (int)(x / scale);
int yc = (int)(y / scale);
int zc = (int)(z / scale);
CellId cell = packCellId(lod, xc, yc, zc);

The voxel coordinates can be computed as:

int vx = (int)(BLOCK_DIMENSION)*(x/scale - xc)) + BLOCK_MARGIN;
int vy = (int)(BLOCK_DIMENSION)*(y/scale - yc)) + BLOCK_MARGIN;
int vz = (int)(BLOCK_DIMENSION)*(z/scale - zc)) + BLOCK_MARGIN;

Once you have this, you can ask the voxel data to the generator object used to generate the world. The clipmapView instance will contain a pointer to this generator. The call looks like:

int outMaterial;
double outVectorX, outVectorY, outVectorZ;
generator->getVoxel(cell, vx, vy, vz, outMaterial, outVectorX, outVectorY, outVectorZ);


0 0
Telarin
That should be helpful, I'll experiment with some of the info this weekend. A couple followup questions:

Re 1) This seems like a fairly important function. Is this something that you guys are planning to add to the Unity Plugin eventually? If so, I'll probably hold off on spending a bunch of time trying to cobble together something and just wait for the official solution.

Re 2) I'm assuming this is something that I will have to extend the Plugin to provide and cannot currently access from the Unity Plugin. Is this correct?

Re 3) What I'm actually doing here is trying to determine the surface material of the initial terrain. I'll be using my own tree manager to place trees in the world initially as it is generated (and to load them back into the same places later on). My placement rules are going to be too complex I think for the built in Voxel Farm functionality to place them for me, and since trees can be removed (chopped down) and grow, I need to make sure that they are only generated once and saved and subsequently loaded as needed. The trick is, to initially place them, I need to be able to test both the height of the terrain at a point (in fact, several points to determine slope) and the material of the terrains surface in order to apply my custom placement rules. If you have better suggestions on how to use functionality already available in VF, I'm certainly open to them. For instance, is there some built in functionality in the engine to test surface slope at a particular point (A gradient would be nice, but even just a scalar field with non-directional slopes would suit my purposes just fine)? I'm assuming again that this is all going to require me extending the plugin a bit, which I am a little hesitant to do with as quickly as you guys are getting features out to us at this point. Again, if any of these features are on the near horizon, I'll just work on other parts of my game and wait for those features to mature. If not, then I'll make an attempt to cobble something together myself.
0 0
voxelfarmtorres
We are compiling a list of things to add to the C# interface. These three rank pretty much at the top.

I am not sure when these will be released, there is 80% chance it will happen within the next two releases.

In these three cases, there is not new behavior code needed. It is more of a plumbing job exposing data we already have to the C# side. It is low risk in general and if you decide to develop it should take you an hour or two.

This getHeight method is optimized, so you should be fine calling it from your instancing system. The Voxel Farm instance layer calls it all the time to place. You can compute the surface slope by making additional calls to getHeight() in a neighborhood and computing the gradient:


        double p0[3] = { x, y, z };
        double y1 = getHeight(instxmax, z, world, biome, layer, heightmap);
        double p1[3] = { instxmax, y1, z };
        double y2 = getHeight(x, instzmax, world, biome, layer, heightmap);
        double p2[3] = { x, y2, instzmax };
        double y3 = getHeight(x, instzmin, world, biome, layer, heightmap);
        double p3[3] = { x, y3, instzmin };
        double y4 = getHeight(instxmin, z, world, biome, layer, heightmap);
        double p4[3] = { instxmin, y4, z };
        double v10[3] =
        {
          p1[0] - p0[0],
          p1[1] - p0[1],
          p1[2] - p0[2]
        };
        double v20[3] =
        {
          p2[0] - p0[0],
          p2[1] - p0[1],
          p2[2] - p0[2]
        };
        double v30[3] =
        {
          p3[0] - p0[0],
          p3[1] - p0[1],
          p3[2] - p0[2]
        };
        double v40[3] =
        {
          p4[0] - p0[0],
          p4[1] - p0[1],
          p4[2] - p0[2]
        };
        double n[3];
        CROSS(n, v20, v10);
        double d = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
        double angle = DOT(n, up) / d;
        CROSS(n, v30, v40);


0 0
ncpaddler
I'm trying to implement this as well ( exposing the getHeight function to C# ).   

In voxelfarm.cs spatial class I added

           [DllImport("voxelfarm")]
            public static extern double getVFHeight(double x, double z);

and in voxelfarm_unity.cpp I tried this:


double VOXELFARM_API getVFHeight(double x, double z)
{
    return vfImpl->vf->getHeight(x, z);
}

then tried to call it from C# :

            myheight = voxelfarm.dll.spatial.getVFHeight(targetX, targetZ);


Somethings not quite right yet, I know this is probably a horrible attempt at this point but any corrections that someone can provide will be much appreciated.
0 0
Ericool
Did you declare and export your function in voxelfarm_unity.h ?
0 0
ncpaddler
I had forgotten to change the declaration from a previous version of the function I was working with.

When I went in to correct it, I noticed all the other exported functions were of type "void".

So I've reworked it accordingly in case that is a requirement but still not working yet. Thanks for your help.
0 0
ncpaddler
I see that they're planning an update this week so all this may be rendered obsolete, but I thought I would post this up anyone in case it can help anyone in the future.

I did get the getHeight function piped through and working in Unity!

Here's how:

In     Program Files (x86)/Voxel Farm/SDK/PluginDLL directory I opened the voxelfarm.sln in Visual Studio

In voxelfarm_unity.cpp I added this function.


void VOXELFARM_API getVFHeight(double x, double z, double* y)
{
    *y = vfImpl->vf->getHeight(x, z);
    
}

Then declared it in voxelfarm_unity.h header file

    void VOXELFARM_API getVFHeight(double x, double z, double* y);
    
Then back in my Unity project folders, under Assets/Voxel Farm Unity Plugin/src I added this to voxelfarm.cs    
    
            [DllImport("voxelfarm")]
            public static extern void getVFHeight(double x1, double z1, ref double y1);

I put this in the static public class spatial area


Then, in my C# code, I can call up the voxel height at any given X,Z position as such:

            double myheight = 0;
            double targetX = (your targetX);
            double targetZ = (your targetZ);

           voxelfarm.dll.spatial.getVFHeight((double) (vfclient.originX+(targetX*10f)),(double) (vfclient.originZ+(-1*targetZ*10f)), ref myheight);

           Debug.Log("height ---> " + ((float)myheight - (float)vfclient.originY)/10f);    

Of course you have to assign your Voxel Farm Client gameObject to vfclient however you wish.

The -1* on targetZ is because Voxelfarm Z is reverse of Unity Z.

End result, now I can place distant trees, structures, or other terrain features!
   
trees.png 
0 0
voxelfarmtorres
Thanks for the contribution. I can confirm the next update (3.0.1.1) does not include a conflicting solution.
0 0
Telarin
ncpaddler: Question for you. Once you rebuild the plugin, how did you update the plugin in Unity? I'm looking at the folder structure, and the dll installed when you follow the VF instructions to install the unity plugin is /Assets/Voxel Farm Unity Plugin/Plugins/voxelfarm.dll.
However, when I rebuild the plugin dll in the solution provided in the SDK, the file being output is VoxelFarmPluginDLL.dll. I'm going to assume that there is more involved here than just copying this dll over and renaming it, and that maybe there need to be some setup changes in the SDK project?
0 0
voxelfarmtorres
Like you mention the build output goes to VoxelFarmPluginDLL.dll, then a post build step is automatically applied, which copies and renames the DLL to its final location:


buildevents.png 
If then you need to update the Voxel Farm plugin for an existing project you must:

  1. Make sure Unity is closed
  2. Delete the current copy of the plugin in your project (Assets/Voxel Farm Unity Plugin)
  3. Copy the plugin from Plugin.Unity\Original\Assets\Voxel Farm Unity Plugin to your project

These steps assume there are no custom modifications to the plugin code inside your project, and that you have kept all modifications inside SDK\Plugin.Unity\Original\Assets\Voxel Farm Unity Plugin
0 0
Ericool
Assuming you build with Release x64 it should copy and rename the dll at the location , otherwise you can simply rename it and replace it in your project , that should do.
0 0
ncpaddler
Yea, I've just been copying the file from my x64/Release folder over to the Unity project plugins folder and renaming it manually as you guessed
0 0
Telarin
Awesome. Yeah, my issue is that the post build process was not running and was throwing me off. I just copied and renamed as you suggested and it worked flawlessly, thanks!
0 0