Skip to content

Commit

Permalink
Add billboard script and example (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
aglitchman authored Apr 14, 2022
1 parent ff30cc3 commit 99e2f70
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 0 deletions.
7 changes: 7 additions & 0 deletions examples/assets/sprites.atlas
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
images {
image: "/builtins/assets/images/logo/logo_256.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
margin: 4
extrude_borders: 0
inner_padding: 0
75 changes: 75 additions & 0 deletions examples/scenes/playground/playground.collection
Original file line number Diff line number Diff line change
Expand Up @@ -662,3 +662,78 @@ embedded_instances {
z: 1.0
}
}
embedded_instances {
id: "billboard_sprite"
data: "components {\n"
" id: \"billboard\"\n"
" component: \"/scene3d/scripts/sprites/billboard.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"look_at_object_id\"\n"
" value: \"/main_camera\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"use_rotation\"\n"
" value: \"false\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" properties {\n"
" id: \"late_update\"\n"
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" properties {\n"
" id: \"late_update_priority\"\n"
" value: \"20.0\"\n"
" type: PROPERTY_TYPE_NUMBER\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"sprite\"\n"
" type: \"sprite\"\n"
" data: \"tile_set: \\\"/examples/assets/sprites.atlas\\\"\\n"
"default_animation: \\\"logo_256\\\"\\n"
"material: \\\"/builtins/materials/sprite.material\\\"\\n"
"blend_mode: BLEND_MODE_ALPHA\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: -8.0
y: 5.0
z: 6.5
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 0.005
y: 0.005
z: 0.005
}
}
3 changes: 3 additions & 0 deletions scene3d/render/render3d.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ M.fov = 0
M.near = 0
M.far = 0
M.view_position = vmath.vector3()
M.view_rotation = vmath.quat() -- Note: it can be nil, if camera doesn't use function `view_from_rotation`.
M.view_world_up = vmath.vector3()
M.view_front = vmath.vector3()
M.view_right = vmath.vector3()
Expand Down Expand Up @@ -94,6 +95,7 @@ function M.view_from_rotation(quat, viewport)
viewport = viewport or M

viewport.view_world_up = M.UP
viewport.view_rotation = quat
viewport.view_front = vmath.rotate(quat, M.FORWARD)
viewport.view_right = vmath.rotate(quat, M.RIGHT)
viewport.view_up = vmath.rotate(quat, M.UP)
Expand All @@ -103,6 +105,7 @@ function M.view_direction(direction, viewport)
viewport = viewport or M

viewport.view_world_up = M.UP
viewport.view_rotation = nil -- Check the note above.
viewport.view_front = direction
-- Re-calculate the Right and Up vector, plus normalize the vectors,
-- because their length gets closer to 0 the more you look up or down
Expand Down
61 changes: 61 additions & 0 deletions scene3d/scripts/sprites/billboard.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
-- Sometimes we'd like to make labels or other things that always face the camera.
-- Add this script as a component to your gameobject to make this happen.

go.property("enabled", true)
go.property("look_at_object_id", hash(""))
go.property("use_rotation", true)
go.property("use_world_transform", false)

go.property("late_update", false)
go.property("late_update_priority", 1)

local render3d = require("scene3d.render.render3d")
local math3d = require("scene3d.helpers.math3d")

local EMPTY_HASH = hash("")

local function update_rotation(self)
if self.use_rotation then
local rotation = render3d.view_rotation
if self.look_at_object_id ~= EMPTY_HASH then
rotation = self.use_world_transform and go.get_world_rotation(self.look_at_object_id) or go.get_rotation(self.look_at_object_id)
end

if rotation then
go.set_rotation(rotation)
return
end
end

local position = self.use_world_transform and go.get_world_position() or go.get_position()
local look_at_pos = render3d.view_position
if self.look_at_object_id ~= EMPTY_HASH then
look_at_pos = self.use_world_transform and go.get_world_position(self.look_at_object_id) or go.get_position(self.look_at_object_id)
end

local rotation = math3d.quat_look_rotation(position - look_at_pos, render3d.UP)
go.set_rotation(rotation)
end

-- This update will happen after game objects have been moved by the physics engine
local function late_update(self)
update_rotation(self)
end

function init(self)
if self.late_update then
self.late_update_id = scene3d.prerender_register(late_update, self.late_update_priority)
end
end

function final(self)
if self.late_update_id then
scene3d.prerender_unregister(self.late_update_id)
end
end

function update(self, dt)
if not self.late_update_id then
update_rotation(self)
end
end

0 comments on commit 99e2f70

Please sign in to comment.