Skip to content

Commit

Permalink
trying out dynamicmesh
Browse files Browse the repository at this point in the history
  • Loading branch information
blinkybool committed Jul 27, 2023
1 parent 65f7fbf commit f16c84a
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 60 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@

*.DS_Store

Packages/**
Packages/**
sourcemap.json
111 changes: 59 additions & 52 deletions lib/Client/SurfaceCanvas.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ local Sift = require(root.Parent.Sift)
local Feather = require(root.Parent.Feather)
local DrawingTask = require(root.DrawingTask)
local PartCanvas = require(root.PartCanvas)
local DynamicMeshCanvas = require(root.DynamicMeshCanvas)

local SurfaceCanvas = {}
SurfaceCanvas.__index = SurfaceCanvas
Expand Down Expand Up @@ -44,14 +45,17 @@ function SurfaceCanvas.new(board)
self:render()
end))

self:_initLoadingStack()
if #self.LoadingStack > 0 then
self.Loading = true
self:_setTransparency()
else
self.Loading = false
self:_setActive()
end
-- self:_initLoadingStack()
-- if #self.LoadingStack > 0 then
-- self.Loading = true
-- self:_setTransparency()
-- else
-- self.Loading = false
-- self:_setActive()
-- end

self.Loading = false
self:render()

return self
end
Expand Down Expand Up @@ -93,7 +97,7 @@ function SurfaceCanvas:_initLoadingStack()
self.LoadedFigures = {}
end

function SurfaceCanvas:LoadMore(lineBudget)
function SurfaceCanvas:LoaDynamicMeshCanvasore(lineBudget)

if self.Loading and #self.LoadingStack > 0 then

Expand Down Expand Up @@ -164,60 +168,63 @@ end

function SurfaceCanvas:render()

local figures, figureMaskBundles
-- local figures, figureMaskBundles

if self.Loading then
-- if self.Loading then

figures = self.LoadedFigures
figureMaskBundles = {}
else
-- figures = self.LoadedFigures
-- figureMaskBundles = {}
-- else

self:_trimUnverified()
-- self:_trimUnverified()

local drawingTasks = Sift.Dictionary.merge(self.Board.DrawingTasks, self.UnverifiedDrawingTasks)
-- local drawingTasks = Sift.Dictionary.merge(self.Board.DrawingTasks, self.UnverifiedDrawingTasks)

figures = table.clone(self.Board.Figures)
figureMaskBundles = {}
-- figures = table.clone(self.Board.Figures)
-- figureMaskBundles = {}

-- Apply all of the drawingTasks to the figures,
-- then all of the unverified ones on top.
-- -- Apply all of the drawingTasks to the figures,
-- -- then all of the unverified ones on top.

for _, family in {drawingTasks, self.UnverifiedDrawingTasks} do
-- for _, family in {drawingTasks, self.UnverifiedDrawingTasks} do

for taskId, drawingTask in pairs(family) do
-- for taskId, drawingTask in pairs(family) do

if drawingTask.Type == "Erase" then
-- if drawingTask.Type == "Erase" then

local figureIdToFigureMask = DrawingTask.Render(drawingTask)
-- local figureIdToFigureMask = DrawingTask.Render(drawingTask)

for figureId, figureMask in pairs(figureIdToFigureMask) do
local bundle = figureMaskBundles[figureId] or {}
bundle[taskId] = figureMask
figureMaskBundles[figureId] = bundle
end
else
figures[taskId] = DrawingTask.Render(drawingTask)
end
end
end
end

local element = Feather.createElement(PartCanvas, {

Figures = figures,
FigureMaskBundles = figureMaskBundles,

CanvasSize = self.Board.SurfaceSize,
CanvasCFrame = self.Board.SurfaceCFrame,
})

if self.CanvasTree then
Feather.update(self.CanvasTree, element)

self.CanvasTree.root.result[1].Parent = self:_getContainer()
else
self.CanvasTree = Feather.mount(element, self:_getContainer(), self.Board:FullName())
end
-- for figureId, figureMask in pairs(figureIdToFigureMask) do
-- local bundle = figureMaskBundles[figureId] or {}
-- bundle[taskId] = figureMask
-- figureMaskBundles[figureId] = bundle
-- end
-- else
-- figures[taskId] = DrawingTask.Render(drawingTask)
-- end
-- end
-- end
-- end

-- local element = Feather.createElement(PartCanvas, {

-- Figures = figures,
-- FigureMaskBundles = figureMaskBundles,

-- CanvasSize = self.Board.SurfaceSize,
-- CanvasCFrame = self.Board.SurfaceCFrame,
-- })

-- if self.CanvasTree then
-- Feather.update(self.CanvasTree, element)

-- self.CanvasTree.root.result[1].Parent = self:_getContainer()
-- else
-- self.CanvasTree = Feather.mount(element, self:_getContainer(), self.Board:FullName())
-- end

local canvas = DynamicMeshCanvas.new(self.Board):CanvasModelAsync()
canvas.Parent = workspace
end

return SurfaceCanvas
2 changes: 1 addition & 1 deletion lib/Config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ Config.PersonalBoard = {
-- WhiteBoardMini: "8545133318"
-- BlackBoardMini: "8545118621"
AssetId = "8545118621",
Enabled = true,
Enabled = false,
-- Position of where the board will spawn relative to the HumanoidRootPart
-- Increase y-value for larger boards
TorsoOffset = Vector3.new(0,2,-5),
Expand Down
170 changes: 170 additions & 0 deletions lib/DynamicMeshCanvas.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
local root = script.Parent
local Config = require(root.Config)

local DynamicMeshCanvas = {}
DynamicMeshCanvas.__index = DynamicMeshCanvas

function DynamicMeshCanvas.new(board)
local self = setmetatable({}, DynamicMeshCanvas)

self._board = board
return self
end

function DynamicMeshCanvas:_vertices(p0: Vector2, p1: Vector2, width: number, zIndex: number)

local function lerp(a, b, t)
if t < 0.5 then
return a + (b - a) * t
else
return b - (b - a) * (1 - t)
end
end

if p0 == p1 then
p0 = p0 + Vector2.new(-width/2, 0)
p1 = p1 + Vector2.new(width/2, 0)
end

local perp = -Vector2.new((p1-p0).Y, -(p1-p0).X).Unit

local sizeX = self._board.SurfaceSize.X
local sizeY = self._board.SurfaceSize.Y
local aspectRatio = sizeX / sizeY

local z =
- Config.SurfaceCanvas.ZThicknessStuds / 2
- Config.SurfaceCanvas.InitialZOffsetStuds
- zIndex * Config.SurfaceCanvas.StudsPerZIndex
local v1 = Vector3.new(
lerp(sizeX / 2, -sizeX / 2, (p0 + perp * width).X / aspectRatio),
lerp(sizeY / 2, -sizeY / 2, (p0 + perp * width).Y),
z
)
local v2 = Vector3.new(
lerp(sizeX / 2, -sizeX / 2, (p0 - perp * width).X / aspectRatio),
lerp(sizeY / 2, -sizeY / 2, (p0 - perp * width).Y),
z
)
local v3 = Vector3.new(
lerp(sizeX / 2, -sizeX / 2, (p1 + perp * width).X / aspectRatio),
lerp(sizeY / 2, -sizeY / 2, (p1 + perp * width).Y),
z
)
local v4 = Vector3.new(
lerp(sizeX / 2, -sizeX / 2, (p1 - perp * width).X / aspectRatio),
lerp(sizeY / 2, -sizeY / 2, (p1 - perp * width).Y),
z
)

return v1, v2, v3, v4
end

local function pivot(v: Vector3, radians: number)
return Vector3.new(
v.X * math.cos(radians) + v.Z * math.sin(radians),
v.Y,
v.X * -math.sin(radians) + v.Z * math.cos(radians)
)
end

function DynamicMeshCanvas:_writeFigureToMesh(figure, mesh: DynamicMesh)
for i=1, #figure.Points-1 do
local p0, p1 = figure.Points[i], figure.Points[i+1]
if not (p0 and p1) then
continue
end

local v1, v2, v3, v4 = self:_vertices(p0, p1, figure.Width, figure.ZIndex)

-- Workaround for bug when making axis-aligned meshes
v1 = pivot(v1, math.pi/4)
v2 = pivot(v2, math.pi/4)
v3 = pivot(v3, math.pi/4)
v4 = pivot(v4, math.pi/4)

local u = v2 - v1
local v = v3 - v1
local normal = u:Cross(v).Unit

local index1 = mesh:AddVertex(v1)
mesh:SetVertexColor(index1, figure.Color)
local index2 = mesh:AddVertex(v2)
mesh:SetVertexColor(index2, figure.Color)
local index3 = mesh:AddVertex(v3)
mesh:SetVertexColor(index3, figure.Color)
local index4 = mesh:AddVertex(v4)
mesh:SetVertexColor(index4, figure.Color)

mesh:SetVertexNormal(index1, normal)
mesh:SetVertexNormal(index2, normal)
mesh:SetVertexNormal(index3, normal)
mesh:SetVertexNormal(index4, normal)

mesh:AddTriangle(index1, index4, index2)
mesh:AddTriangle(index1, index3, index4)
end
end

-- Returns a Model containing one mesh per curve
function DynamicMeshCanvas:CurvesModelAsync(): Model

local model = Instance.new("Model")
for figureId, figure in self._board.Figures do

local dynamicMesh = Instance.new("DynamicMesh")
self:_writeFigureToMesh(figure, dynamicMesh)
if #dynamicMesh:GetVertices() == 0 then
continue
end

dynamicMesh.Parent = workspace
local figuresPart = dynamicMesh:CreateMeshPartAsync(Enum.CollisionFidelity.Box)
dynamicMesh:Destroy()

figuresPart.CanCollide = false
figuresPart.Anchored = true
figuresPart.Material = Enum.Material.Neon

-- correct for pivot
figuresPart.CFrame = self._board.SurfaceCFrame * CFrame.Angles(0, -math.pi/4, 0)
figuresPart.Name = figureId
figuresPart.Parent = model
end

return model
end

-- Returns a meshpart for the whole canvas
function DynamicMeshCanvas:CanvasModelAsync(): Model

local model = Instance.new("Model")
local dynamicMesh = Instance.new("DynamicMesh")
for _, figure in self._board.Figures do
self:_writeFigureToMesh(figure, dynamicMesh)
end

local success, numTriangles = pcall(function()
return #dynamicMesh:GetVertices() == 0
end)

if not success or numTriangles == 0 then
return model
end

dynamicMesh.Parent = workspace
local figuresPart = dynamicMesh:CreateMeshPartAsync(Enum.CollisionFidelity.Box)
dynamicMesh:Destroy()

figuresPart.CanCollide = false
figuresPart.Anchored = true
figuresPart.Material = Enum.Material.Neon

-- correct for pivot
figuresPart.CFrame = self._board.SurfaceCFrame * CFrame.Angles(0, -math.pi/4, 0)
figuresPart.Parent = model

return model
end

return DynamicMeshCanvas
8 changes: 7 additions & 1 deletion lib/PartCanvas/Curve.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ local partInitProps = {
CanQuery = false, -- Does not take part in e.g. GetPartsInPart
}

local zBlockMesh = e("BlockMesh", {
Scale = Vector3.new(1,1,0),
})

local function circle(props)

local point, color, width, zIndex, canvasSize, canvasCFrame = unpack(props)
Expand Down Expand Up @@ -59,6 +63,7 @@ local function circle(props)
Color = color,

[Feather.HostInitProps] = partInitProps,
-- [Feather.Children] = {xBlockMesh}
})
end

Expand Down Expand Up @@ -103,7 +108,8 @@ local function line(props)

Color = color,

[Feather.Children] = (roundedP0 or roundedP1) and {firstCircle, secondCircle} or nil,
-- [Feather.Children] = (roundedP0 or roundedP1) and {firstCircle, secondCircle} or nil,
[Feather.Children] = (roundedP0 or roundedP1) and {firstCircle, secondCircle, zBlockMesh} or {zBlockMesh},

[Feather.HostInitProps] = partInitProps,
})
Expand Down
1 change: 1 addition & 0 deletions lib/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ return {
Figure = require(script.Figure),
Server = require(script.Server),
Client = require(script.Client),
DynamicMeshCanvas = require(script.DynamicMeshCanvas),
}
Loading

0 comments on commit f16c84a

Please sign in to comment.