Skip to main content

VoxelEdit

Client Server

Deprecated

The voxel edit functions in this class are old and may not correctly work. Instead use Vox.

Server Only

Currently voxel edits can only be done on the server side.

Use this class to create voxel edits.

Use this class by first creating a VoxelEdit object, then setting the properties such as shape and color and finally calling one of the edit methods:

  • Paint()
  • Add()
  • Remove()
  • Copy()
  • Kernel()
A function to make a voxel capsule from position 1 to position 2
function self:makeLine(p1, p2)
--first create a VoxelEdit object
local ve = VoxelEdit()

--modify some properties
local thickness = 0.2
ve.shape = Capsule(p1, p2, thickness)
ve.color = Vec3(1, 0, 1)

--call the edit method
ve:Add()
end

Every scene has only one static voxel data and can have multiple dynamic voxel data. The static voxel data is used for the world and can not be moved. However both can be edited. To choose whether to edit the static or dynamic voxel data, use the filter property.

Creating dynamic voxel data attached to an object
--create an object with voxel data (renders itself)
local ob = Scene:CreateObject("Voxel Sphere")
local vd = ob:AddComponent("VoxelData")
local vres = VoxelDataResource() --new empty voxel data
vd.data = vres
ob.pos = Vec3(0, 30, 0)

--voxel edit
local ve = VoxelEdit()

--target the object and ignore static voxels
ve.filter.useStatic = false
ve.filter.forceList = { ob }

--add sphere
ve.color = Vec3(0,0.5,1)
ve.shape = Sphere(ob.pos, 1)
ve:Add()

Use the copy operation to copy voxels from one object to others or the static voxel data.

Copy from voxel object to static voxel data
--select some object with voxel data here
local copyFrom = Scene:GetObjectByName("Voxel Sphere")

local ve = VoxelEdit()

--make a box fitting the target to copy from
local b = Box()
local center, size = copyFrom:GetComponentByType("VoxelData"):GetBounds()
b.pos = center
b.size = size
ve.shape = b
ve.filter.useNotStatic = false

--select what data to copy and its pasted transformation
ve.copyResource = copyFrom:GetComponentByType("VoxelData").data
ve.copyDestinationPos = copyFrom.pos
ve.copyDestinationRot = copyFrom.rot
ve.copyDestinationScale = copyFrom.scale
ve:Copy()

See a different example here

Constructors​

VoxelEdit VoxelEdit()​

VoxelEdit VoxelEdit(Shape shape)​

VoxelEdit VoxelEdit(Shape shape, Vec3 position)​

Methods​

nil Flush()​

Flush() adds a special operation in the queue, which waits for all running ops to finish. If we had flush after each op, it would eliminate all multithreaded processing.

nil Paint()​

Change the color of voxels

nil Add()​

Add voxels

nil Remove()​

Remove voxels

nil Copy()​

Copy voxels somewhere

nil Kernel()​

Smoothing/Inflate/Deflate

Image CaptureImage(Mat4 textureUvTmWorld, number relBorderSize)​

nil FreeTmpLayers(integer clientId)​

It projects cone on voxel geometry and everything inside will be copies to tmp all raycasts will collide with this tmp layer instead until FreeTmpLayers

nil FillTmpLayers(TmpLayerFlags layerFlags, Vec3 camPos, Vec3[] targets, number targetRadius, integer clientId)​

It projects cone on voxel geometry and everything inside will be copies to tmp all raycasts will collide with this tmp layer instead until FreeTmpLayers parameters specify "cone" - two positions and end radius

string[] GetMaterialNames()​

table GetMaterial(string materialName)​

nil SetMaterial(string materialName, table matData)​

nil SetStaticSceneMaterial(string materialName, number roughness, number metallicity)​

nil SetVoxelDataResourceMaterial(VoxelData vd, string materialName)​

nil ReplaceVoxelDataResourceMaterial(VoxelData vd, string destMaterialName, string srcMaterialName, boolean clearSourceMat)​

nil BackupSurfaceAttributes()​

Properties​

boolean blendEnable​

BlendMode blendMode​

Various blend modes which you may know from Photoshop. See a list of explanations here.

number blendOpacity​

number blendRadiusRatio​

Color color​

Filter filter​

Shape shape​

if shape is nil the operation will match all targets

boolean clampToMinVoxelSize​

if ClampToMinVoxelSize is true (it's default), it sets size of shape to at least size of voxel size of target. This can interfere with your box size if it's too small.

Object copySourceTr​

Object copyDestinationTr​

Vec3 copyDestinationPos​

Quat copyDestinationRot​

number copyDestinationScale​

Vec3 copySourcePos​

Quat copySourceRot​

number copySourceScale​

VoxelData copyResource​

boolean colorEnable​

boolean normalEnable​

boolean roughnessEnable​

boolean metallicityEnable​

boolean materialEnable​

number roughness​

number metallicity​

RemoveType removeType​

number removeHardness​

boolean useMaterialColor​

string material​

table<string,number> removeList​

table<string,number> carveList​

string[] removeCountList​

boolean removeStats​

boolean usesPbr​

CopyOperation copyOperation​

InsertOperation insertOperation​

integer kernelType​

0 = Smooth 7x5x7 1 = Smooth 3x3x3 2 = Smooth 5x5x5 3 = Inflate 4 = Deflate 5 = Normals smooth 6 = Normals sharp

Asset|AssetLink|Image imageColor​

Asset|AssetLink|Image imageNormal​

Mat4 imageUVTm​

boolean imageUVClamp​

boolean imageTriplanar​

Triplanar projection — samples the image along world X/Y/Z so it covers every face, with the tiling grid anchored in world space. When false, the image is planar-projected along a single direction.

boolean imageNormalOverwrite​

When true, the image's normal map replaces the surface normal (flattening to bare geometry if the texture has no normal); when false it blends into the existing surface normal.

boolean imageProjectionFade​

Planar projection only: fade the albedo on faces angled away from the projection axis (decal-style, lands only on the facing face). Ignored for triplanar, which covers every face.

number imageNormalBlendPower​

fun(progress:number) onProgress​

callback function. progress from 0-1. May not be called every frame. Is called after script updates

fun(info:RemoveCountInfo, computeTimeMs:number) onFinished​

callback function. onFinished is called after onProgress if it was last part

fun(reason:string, opCount:integer) onError​

callback function. Called when the op group is dropped: reason says why, opCount is how many ops that group covered