Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

"Splash" decal api, and adapting it to include connected parts?

Asked by
Edenojack 171
8 years ago

I have a module that can apply a texture to a specific point on a part, and can also bend the texture around a corner. However, when two parts are connected, to make a wall lets say, the texture will stay on the part and curve around its wall, rather than continuing onto the other part to make a seamless texture.

I'd like to be able to, if possible, find the parts that overlap in a selected texture area, see if the create a face, and then apply the texture between them.

I just don't know how atm :/

I am using the following code:

local Textures = {"417236023"}
local Texture = "http://www.roblox.com/asset/?id=333740402"--<Your image or whatever
local PicSize = 10 --How many "pixels" the image is (Always square shape)
local CanSize = 10 --10 pixels offset, unless replacing the Picture for something made of frames, not necessary to change
local DelayRemove = 0

local textureAPI = {}

function ReturnNormal(PartCF,RayNorm)
    if PartCF.lookVector - RayNorm == Vector3.new(0,0,0) then
        return "Front",5
    elseif PartCF.lookVector + RayNorm == Vector3.new(0,0,0) then
        return "Back",2
    else
        local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = PartCF:components()
        if Vector3.new(R01,R11,R21) == RayNorm then
            return"Top", 1
        elseif Vector3.new(-R01,-R11,-R21) == RayNorm then
            return "Bottom",4
        elseif Vector3.new(-R00,-R10,-R20) == RayNorm then
            return "Left",3
        elseif Vector3.new(R00,R10,R20) == RayNorm then
            return "Right",0
        end
    end
end

function SecondaryTex(OldFace,LastPos,Dir,part,pos,lastABSS,lastABSP)
    local SizeWidth = part.Size.X
    local SizeHeight = part.Size.Y
    local Face,Val
    local Offset = -SizeWidth+((part.CFrame:toObjectSpace(CFrame.new(pos))).p.Z/(SizeWidth))
    if Dir == 1 then
        if OldFace == "Front" then
            Face,Val = "Right",0
        elseif OldFace == "Right" then
            Face,Val = "Back",2
        elseif OldFace == "Left" then
            Face,Val = "Front",5 --Bit redundant tbf
        elseif OldFace == "Back" then
            Face,Val = "Left",3
        end
    else
        if OldFace == "Front" then
            Face,Val = "Left",3
        elseif OldFace == "Right" then
            Face,Val = "Front",5
        elseif OldFace == "Left" then
            Face,Val = "Back",2
        elseif OldFace == "Back" then
            Face,Val = "Right",0
        end
    end
    if Face == "Right" or Face == "Left" then
        SizeWidth = part.Size.Z
        SizeHeight = part.Size.Y
        Offset = -SizeWidth+((part.CFrame:toObjectSpace(CFrame.new(pos))).p.X/(SizeWidth))
    end
    --print(OldFace,LastPos,Dir,part,pos)
    --print(Enum.NormalId[Face])
    local surface
    local frame
    if Face == nil then
        return
    end
    for _,i in pairs(part:GetChildren()) do
        if i:IsA("SurfaceGui") then
            if i.Face == Enum.NormalId[Face] then
                surface = i
                frame = surface.Framey
                print(surface.Face,"Found")
            end
        end
    end
    if surface == nil then
        surface = Instance.new("SurfaceGui", part)
        surface.CanvasSize = Vector2.new(SizeWidth*CanSize,SizeHeight*CanSize)
        surface.Face = Val
        print(surface.Face,"Made")
        frame = Instance.new("Frame", surface)
        frame.Name = "Framey"
        frame.Size = UDim2.new(1,0,1,0)
        frame.ClipsDescendants = true
        frame.BackgroundTransparency =1 
    end
        local Tex = Instance.new("ImageLabel",frame)
        Tex.Image = Texture
        Tex.Size = UDim2.new(0,PicSize,0,PicSize)
        Tex.BackgroundTransparency = 1
            if Dir == 0 then
                Tex.Position = UDim2.new(0,Dir-(lastABSS-lastABSP),LastPos.Y.Scale,LastPos.Y.Offset)
            else
                Tex.Position = UDim2.new(1,(lastABSP),LastPos.Y.Scale,LastPos.Y.Offset)
            end
            if DelayRemove~=0 then
                game.Debris:AddItem(Tex,DelayRemove)
            end
return
end

function textureAPI.ApplyTo(part,pos,normal,ID,ImgSize)
    if ID ~= nil then
        Texture = "http://www.roblox.com/asset/?id="..ID
    else
        Texture = "http://www.roblox.com/asset/?id=417236023"
    end
    if ImgSize~= nil then
        PicSize = ImgSize
    end
    local SizeWidth = part.Size.X
            local SizeHeight = part.Size.Y
            local Face,Val = ReturnNormal(part.CFrame,normal)
            print(Face,Val)
            if Face == nil then
                return
            end
            if Face == "Top" or Face == "Bottom" then
                SizeWidth = part.Size.Z
                SizeHeight = part.Size.X
            elseif Face == "Right" or Face == "Left" then
                SizeWidth = part.Size.Z
                SizeHeight = part.Size.Y
            end
            local surface
            local frame
                for _,i in pairs(part:GetChildren()) do
                    if i:IsA("SurfaceGui") then
                        print(i.Face,Val, i.Face==Enum.NormalId[Face])
                        if i.Face == Enum.NormalId[Face] then
                            surface = i
                            frame = surface.Framey
                        end
                    end
                end
            if surface == nil then
                surface = Instance.new("SurfaceGui", part)
                surface.CanvasSize = Vector2.new(SizeWidth*CanSize,SizeHeight*CanSize)
                surface.Face = Val
                frame = Instance.new("Frame", surface)
                frame.Name = "Framey"
                frame.Size = UDim2.new(1,0,1,0)
                frame.ClipsDescendants = true
                frame.BackgroundTransparency =1 
            end
            local Tex = Instance.new("ImageLabel",frame)
            Tex.Image = Texture
            Tex.Size = UDim2.new(0,PicSize,0,PicSize)
            Tex.BackgroundTransparency = 1
            local Size = -(part.CFrame:toObjectSpace(CFrame.new(pos))).p
            if Face == "Front" then
                Tex.Position = UDim2.new(.5+(Size.X/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2)
            elseif Face == "Back" then
                Tex.Position = UDim2.new(.5+(-Size.X/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2)
            elseif Face == "Right" then
                Tex.Position = UDim2.new(.5+(Size.Z/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2)
            elseif Face == "Left" then
                Tex.Position = UDim2.new(.5+(-Size.Z/(SizeWidth)),-PicSize/2,.5+(Size.Y/(SizeHeight)),-PicSize/2)
            elseif Face == "Top" then
                Tex.Position = UDim2.new(.5+(Size.Z/(SizeWidth)),-PicSize/2,.5+(-Size.X/(SizeHeight)),-PicSize/2)
            elseif Face == "Bottom" then
                Tex.Position = UDim2.new(.5+(Size.Z/(SizeWidth)),-PicSize/2,.5+(Size.X/(SizeHeight)),-PicSize/2)
            end
            if Tex.AbsolutePosition.X>(surface.AbsoluteSize.X-PicSize) then
                SecondaryTex(Face,Tex.Position,0,part,pos,surface.AbsoluteSize.X,Tex.AbsolutePosition.X)
            elseif Tex.AbsolutePosition.X<(PicSize/2) then
                print(surface.AbsoluteSize.X,Tex.AbsolutePosition.X)
                SecondaryTex(Face,Tex.Position,1,part,pos,surface.AbsoluteSize.X,Tex.AbsolutePosition.X)
            end
            if DelayRemove~=0 then
                game.Debris:AddItem(Tex,DelayRemove)
            end
end

return textureAPI

Theres likely a lot of redundant code in there, but optimizing is not overly important at the mo. If anyone has any suggestions, I'd greatly appreciate it!

Answer this question