richeyrose
Hiya,
So I've got to the stage where I want to start loading prefabs into my level at runtime, basically reproducing the elastic box functionality of Voxel studio eventually but for now just spawning and voxelizing a prefab and I'm pretty stumped. I can create a CArchitectureManager layer and add it to the world using the CGenerator class, and can see that I can voxelize a prefab once it has been set up through the CClipmapView stampModel() method, but I can't work out the steps I need to take to get the Architecture Manager to actually produce anything. I'm going from the ElasticBox.cpp class in the VoxelFarmDemoBundled but am having issues in that its not actually called anywhere so I can't work out how to set up the parameters for the CArchitectureManager or stampModel() methods.

Can you explain the steps to me - so far I think I need to do the following (with added questions!)- 

1) I create a CArchitectureManager object and then I need to load a Prefab (and module(s)? what's the difference in this context?) and whatever meshes are referenced in the "instance" commands in the grammar using the loadModule(), loadPrefab(), loadMesh() methods.

2) Are these meshes and code files contained in the UE4 bundle exported by VoxelStudio and I just need to reference them by filename e.g. "bridge" or "bridge.code" and "wall_1m" / "wall_1m.dat" or do I somehow need to load them into UE4 at runtime from an external directory as they can't be imported as UAssets.

3)Also can I use .fbx files as in Voxel studio as I'd rather not have to write a file converter?

4) Once I've done the above I then guess I need to use the addEntity() method to say where I want the prefab to spawn. Presumably I need to convert between UE4 space and VoxelFarm space at this point and feed these in.

5)I also need to include the "classId" as a parameter in addEntity(). Is this the "id" I've just passed into loadModule()? what about the id I've just passed into loadPrefab()?

6)TMap<String, int>* materials - I don't know where this conversion from "alphanumeric material indentifiers as they appear in grammar source code to integer material IDs as they are defined in the realtime material library" happens to allow me to construct this TMap.

7) Once I've specified groundlevel and decay (what does this variable do, it doesn't seem to be documented anywhere) I guess I then call the CClipmapView stampModel() method (or maybe the CArchitectureManager stampModel() method?) 

8) For the CClipmapView stampModel() method I need to pass in the Size (x, y, z in what units?) the Rotations (plural?), the Scope(what is this?), the architecureManager, the moduleId (is this the classId from addEntity?), and then a CPaletteDesc*, a PaletteType and an IMeshStamMaterialSource* that I also don't know how to define.

Basically can I beg you for an example that shows how to set up and spawn a prefab into the world, because I really can't work this out and am rapidly approaching the rocking in a corner sobbing to myself stage.
0 0
voxelfarmtorres
There is one example of this in the SDK. Look for the "ElasticBox" class in the VoxelFarmDemoBundled example. This class is implemented in ElasticBox.h and ElasticBox.cpp

In particular look for the "endBox()" method, where the prefab is voxelized:

void ElasticBox::endBox(
VoxelFarm::CClipmapView* view,
VoxelFarm::Architecture::CArchitectureManager* architectureManager,
int moduleId,
VoxelFarm::Architecture::CPaletteDesc* palette,
VoxelFarm::Architecture:😋aletteType type,
VoxelFarm::IMeshStamMaterialSource* materials)


About FBX support, since FBX is a closed format you need to use Adobe's FBX SDK. We can share how we wrap the FBX calls into a Voxel Farm IMeshStampSource, but the actual FBX SDK is something you must procure separately. 
0 0
richeyrose
Hiya,
Yep I've got that, like I said "I'm going from the ElasticBox.cpp class in the VoxelFarmDemoBundled but am having issues in that its not actually called anywhere so I can't work out how to set up the parameters for the CArchitectureManager or stampModel() methods." Unless I'm missing something nowhere in any of the examples is the architectureManager actually set up to do anything. It is this stage that I am having issues with.
endBox() is basically a wrapper for the stampModel() method:


void ElasticBox::endBox(
VoxelFarm::CClipmapView* view,
VoxelFarm::Architecture::CArchitectureManager* architectureManager,
int moduleId,
VoxelFarm::Architecture::CPaletteDesc* palette,
VoxelFarm::Architecture:😋aletteType type,
VoxelFarm::IMeshStamMaterialSource* materials)
{
Mode = false;
PrevSize[0] = Size[0];
PrevSize[1] = Size[1];
PrevSize[2] = Size[2];

view->stampModel(Size, Rotations, Scope[0], architectureManager, moduleId, palette, type, materials);
}


I can happily pass a pointer to an architectureManager into the equivalent of an endBox() method but unless I can initialise the CArchitectureManager I'm pointing to to something containing actual architecture (i.e. load a prefab, a module (not sure what the difference is in this context, see the question), a mesh etc.) its just going to be an empty layer. I have the same issue with the Scope, moduleId, palette, type and materials parameters in that I don;t know how to set these to something meaningful because there are no examples or explanations of how to do this since the endBox() method isn't called by anything in the example so none of these parameters are actually set up, only declared. I hope that makes sense? Basically the endBox() method tells me nothing except what function I need to call as it is just a wrapper around the stampModel() function.
0 0
voxelfarmtorres
I apologize for skimming your post early.

If you are using CArchitectureManager, you would only need to declare an instance of the object and proceed to load your prefabs and meshes there:


CArchitectureManager testArchMan;
testArchMan.loadPrefab(0, "C:\\mytestprefab.code"); // here we assign Id 0 to the prefab
testArchMan.loadMesh("wall_1m", "C:\\box.dat"); // register a mesh for each instance ID


loadPrefab() and loadModule() are interchangeable in this case.

You could skip the CArchitectureManager altogether. This layer is not necessary for evaluating prefabs, it is meant for providing on-the-fly voxelization of prefabs, which is something you do not need in this case.

The approach without CArchitectureManager is more verbose, but will provide more control:


// Create grammar object
CGrammar* grammar = VF_NEW CGrammar();

// Create module object and name it "main"
CModule* module = &grammar->define("main");
module->baseAxiom = "main";

// Load code from file
module->loadFromFile("C:\\mytestprefab.code");

CEvaluator evaluator;
evaluator.instanceCreator = &collector; // you must provide your own interface implementation to collect all instances here

// set up coordinates
evaluator.root.scope.sx = (float)boxSize[0] / 10.0f;
evaluator.root.scope.sy = (float)boxSize[1] / 10.0f;
evaluator.root.scope.sz = (float)boxSize[2] / 10.0f;
evaluator.root.scope.ax = 0;
evaluator.root.scope.ay = 0;
evaluator.root.scope.az = 0;
evaluator.root.scope.x = 0.0f;
evaluator.root.scope.y = 0.0f;
evaluator.root.scope.z = 0.0f;
evaluator.rootOffsetX = boxWorldPos[0];
evaluator.rootOffsetY = boxWorldPos[1];
evaluator.rootOffsetZ = boxWorldPos[2];

// Run evaluation
// This will produce multiple calls into the IInstanceCreator callback interface
evaluator.run(*grammar, "main", NULL, -1);


At this point, your implementation of IIstanceCreator will have knowledge of all instanced emitted by the prefab and their transformation matrices. You could then proceed to stamp these instances using the traditional stamp mesh functions.

If you are in UE4, this can make a difference, since you get to control how many instances are voxelized at once.
0 0
richeyrose
Thanks! I shall have a go and will undoubtedly be back with more questions soon 🙂
0 0
richeyrose
Hiya,
I'm still completely stuck. I still can't get the architecture manager to spawn anything because I still don't know how to set the parameters for the CClipmapView::stampModel() method. I also can't work out how to implement the instanceCreator in your second example as there's no example implementation to go on I can see. This is what I've got so far using the ArchitectureManager:


void UBuilderVoxelFarmHandler::GetvfWorld(AVoxelFarmWorldActor* VoxelFarmWorldActor)
{
VF_UEC::BundleWorld* vfWorld = VoxelFarmWorldActor->vfWorld;
if (vfWorld)
{
auto ArchitectureManager = vfWorld->architectureManager;
if (ArchitectureManager)
{
ArchitectureManager->loadPrefab(0, "D:\\Cube.code");
ArchitectureManager->loadMesh("wall_1m", "D:\\wall_1m.dat");

VoxelFarm::CClipmapView* clipmapView = vfWorld->clipmapView;
const double size[3] = { 1000, 1000, 1000 };
/// Rotation of box
VoxelFarm::Algebra::Quaternion rotations = { 0,0,0,0 };
/// Origin of box - have also tried this in vf co-ords
const double position[3] = { 0, 0, 0 };
/// ?
VoxelFarm::Architecture::CPaletteDesc* palette = &vfWorld->paletteDescLibrary->paletteIndex[0];
/// ?
VoxelFarm::Architecture:😋aletteType type = VoxelFarm::Architecture:😋aletteType:😋T_DEFAULT;
/// ?
VoxelFarm::IMeshStamMaterialSource* materials;

clipmapView->stampModel(size, rotations, position, ArchitectureManager, 0, palette, type, materials);
}
}
}


I'm assuming that loadPrefab and loadMesh are working, though I can't tell as they don't return anything and I can put anything into them as a path.

I'm not sure whether position is supposed to be in voxel farm or UE4 coordinates. 

CPaletteDesc is a map between a string and an int and is a collection of materials, but I can't work out how its supposed to be populated and I'm still mystified by what IMeshStamMaterialSource is supposed to do - I really don't know what "It translates a given material depending of the position in the world," means, why translateMaterial() is a pure virtual function with a default implementation, or why stampModel() and other functions need this information.

I feel like there's this enormous, complicated but really really useful and powerful chunk of VoxelFarm that's really inaccessible because there's no example implementation of it to build on or explore and the documentation is so sparse. Sorry if I come across as bad tempered but I'm getting very frustrated.
0 0
richeyrose
So, do you think you might be able to help me with the prefab system or is this not something you're interested in supporting?
0 0
voxelfarmtorres
We are interested in supporting you. We have one of our programmers looking at this now. We'll get back to you here.
0 0
richeyrose
That's fantastic,thank you. You've made my evening.
0 0
richeyrose
Hiya, is there any update from your programmer?
0 0
voxelfarmtorres
Yes, I can confirm this is scheduled for the next SDK release (3.0.1.7), which will happen this month (Dec 2018)

The example will be included in the OpenGL demo that loads a bundle.
0 0
richeyrose
That's awesome! Many thanks.
0 0
richeyrose
Hiya, is it possible to get access to the latest version of the SDK please. I've upgraded to the pro license and am beginning to get more of a feel for things but am still struggling as I can't seem to assign materials to prefab instances so am getting access violations. 
Cheers!
0 0
voxelfarmtorres
We have emailed you the new demo with the prefab evaluation and stamping code.

prefabs.png 
0 0
richeyrose
Hiya, Thank you for that. I've managed to get the demo building and running from visual studio in Win32 release and x64 debug mode by changing the materials path and textures directories back to what they were in the original Demo.Bundled as without that I get "Can't find bitmap" errors. However pressing B doesn't seem to do anything currently. Downloading a fresh version of voxelfarm to see if I've screwed up anything in the file structure in the meantime.
Best,
Richard
0 0