Look-based placement of blocks with axial rotation

master
Marc Gilleron 2020-07-28 21:20:37 +01:00
parent ad54c1706a
commit cf8b6b4b22
4 changed files with 54 additions and 22 deletions

View File

@ -34,49 +34,49 @@ func _init():
"directory": "",
"gui_model": "",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [0],
"voxels": ["air"],
"transparent": true
})
_create_block({
"name": "dirt",
"gui_model": "dirt.obj",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [1],
"voxels": ["dirt"],
"transparent": false
})
_create_block({
"name": "grass",
"gui_model": "grass.obj",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [2],
"voxels": ["grass"],
"transparent": false
})
_create_block({
"name": "log",
"gui_model": "log_y.obj",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [3],
"rotation_type": ROTATION_TYPE_AXIAL,
"voxels": ["log_x", "log_y", "log_z"],
"transparent": false
})
_create_block({
"name": "planks",
"gui_model": "planks.obj",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [7],
"voxels": ["planks"],
"transparent": false
})
_create_block({
"name": "stairs",
"gui_model": "stairs_nx.obj",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [6],
"voxels": ["stairs_nx"],
"transparent": false
})
_create_block({
"name": "tall_grass",
"gui_model": "tall_grass.obj",
"rotation_type": ROTATION_TYPE_NONE,
"voxels": [8],
"voxels": ["tall_grass"],
"transparent": true,
"backface_culling": false
})
@ -98,6 +98,14 @@ func _create_block(params: Dictionary):
"backface_culling": true,
"directory": params.name
})
for i in len(params.voxels):
var vname = params.voxels[i]
var id = _voxel_library.get_voxel_index_from_name(vname)
if id == -1:
push_error("Could not find voxel named {0}".format([vname]))
assert(id != -1)
params.voxels[i] = id
var block = Block.new()
block.id = len(_blocks)
@ -114,7 +122,7 @@ func _create_block(params: Dictionary):
_blocks.append(block)
func _defaults(d, defaults):
static func _defaults(d, defaults):
for k in defaults:
if not d.has(k):
d[k] = defaults[k]

View File

@ -20,30 +20,30 @@ collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
[sub_resource type="Voxel" id=3]
voxel_name = "grass"
random_tickable = true
geometry_type = 2
custom_mesh = ExtResource( 1 )
random_tickable = true
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
[sub_resource type="Voxel" id=4]
voxel_name = "log_x"
random_tickable = true
geometry_type = 2
custom_mesh = ExtResource( 4 )
random_tickable = true
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
[sub_resource type="Voxel" id=5]
voxel_name = "log_y"
random_tickable = true
geometry_type = 2
custom_mesh = ExtResource( 3 )
random_tickable = true
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
[sub_resource type="Voxel" id=6]
voxel_name = "log_z"
random_tickable = true
geometry_type = 2
custom_mesh = ExtResource( 5 )
random_tickable = true
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
[sub_resource type="Voxel" id=7]

View File

@ -21,7 +21,7 @@ export(NodePath) var terrain_path = null
export(Material) var cursor_material = null
# TODO Eventually invert these dependencies
onready var _head = get_parent().get_node("Camera")
onready var _head : Camera = get_parent().get_node("Camera")
onready var _hotbar = get_node("../HotBar")
var _terrain = null
@ -50,7 +50,7 @@ func _ready():
_terrain_tool = _terrain.get_voxel_tool()
func get_pointed_voxel():
func _get_pointed_voxel():
var origin = _head.get_global_transform().origin
var forward = -_head.get_transform().basis.z.normalized()
var hit = _terrain_tool.raycast(origin, forward, 10)
@ -61,7 +61,7 @@ func _physics_process(delta):
if _terrain == null:
return
var hit = get_pointed_voxel()
var hit = _get_pointed_voxel()
if hit != null:
_cursor.show()
_cursor.set_translation(hit.position)
@ -82,7 +82,7 @@ func _physics_process(delta):
var pos = hit.previous_position
if has_cube == false:
pos = hit.position
if can_place_voxel_at(pos):
if _can_place_voxel_at(pos):
var block_id = _hotbar.get_selected_block_type()
if block_id != -1:
_place_single_block(pos, block_id)
@ -110,7 +110,8 @@ func _unhandled_input(event):
_hotbar.select_slot(slot_index)
func can_place_voxel_at(pos: Vector3):
func _can_place_voxel_at(pos: Vector3):
# TODO Is it really relevant anymore? This demo doesn't use physics
var space_state = get_viewport().get_world().get_direct_space_state()
var params = PhysicsShapeQueryParameters.new()
params.collision_mask = COLLISION_LAYER_AVATAR
@ -124,14 +125,26 @@ func can_place_voxel_at(pos: Vector3):
func _place_single_block(pos: Vector3, block_id: int):
var block = Blocks.get_block(block_id)
var voxel_id = block.voxels[0]
# TODO Handle rotated variants etc
var block := Blocks.get_block(block_id)
var voxel_id := 0
match block.rotation_type:
Blocks.ROTATION_TYPE_NONE:
voxel_id = block.voxels[0]
Blocks.ROTATION_TYPE_AXIAL:
var look_dir := -_head.get_transform().basis.z
var axis := Util.get_longest_axis(look_dir)
voxel_id = block.voxels[axis]
_:
# Unknown value
assert(false)
_place_single_voxel(pos, voxel_id)
func _place_single_voxel(pos, type):
func _place_single_voxel(pos: Vector3, type: int):
_terrain_tool.channel = VoxelBuffer.CHANNEL_TYPE
_terrain_tool.value = type
_terrain_tool.do_point(pos)

View File

@ -84,3 +84,14 @@ static func get_triangle_normal(a: Vector3, b: Vector3, c: Vector3) -> Vector3:
var v = (a - c).normalized()
return v.cross(u)
static func get_longest_axis(v: Vector3) -> int:
var lx = abs(v.x)
var ly = abs(v.y)
var lz = abs(v.z)
if lx > ly and lx > lz:
return Vector3.AXIS_X
if ly > lx and ly > lz:
return Vector3.AXIS_Y
return Vector3.AXIS_Z