Look-based placement of blocks with axial rotation
parent
ad54c1706a
commit
cf8b6b4b22
|
@ -34,49 +34,49 @@ func _init():
|
||||||
"directory": "",
|
"directory": "",
|
||||||
"gui_model": "",
|
"gui_model": "",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_NONE,
|
||||||
"voxels": [0],
|
"voxels": ["air"],
|
||||||
"transparent": true
|
"transparent": true
|
||||||
})
|
})
|
||||||
_create_block({
|
_create_block({
|
||||||
"name": "dirt",
|
"name": "dirt",
|
||||||
"gui_model": "dirt.obj",
|
"gui_model": "dirt.obj",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_NONE,
|
||||||
"voxels": [1],
|
"voxels": ["dirt"],
|
||||||
"transparent": false
|
"transparent": false
|
||||||
})
|
})
|
||||||
_create_block({
|
_create_block({
|
||||||
"name": "grass",
|
"name": "grass",
|
||||||
"gui_model": "grass.obj",
|
"gui_model": "grass.obj",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_NONE,
|
||||||
"voxels": [2],
|
"voxels": ["grass"],
|
||||||
"transparent": false
|
"transparent": false
|
||||||
})
|
})
|
||||||
_create_block({
|
_create_block({
|
||||||
"name": "log",
|
"name": "log",
|
||||||
"gui_model": "log_y.obj",
|
"gui_model": "log_y.obj",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_AXIAL,
|
||||||
"voxels": [3],
|
"voxels": ["log_x", "log_y", "log_z"],
|
||||||
"transparent": false
|
"transparent": false
|
||||||
})
|
})
|
||||||
_create_block({
|
_create_block({
|
||||||
"name": "planks",
|
"name": "planks",
|
||||||
"gui_model": "planks.obj",
|
"gui_model": "planks.obj",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_NONE,
|
||||||
"voxels": [7],
|
"voxels": ["planks"],
|
||||||
"transparent": false
|
"transparent": false
|
||||||
})
|
})
|
||||||
_create_block({
|
_create_block({
|
||||||
"name": "stairs",
|
"name": "stairs",
|
||||||
"gui_model": "stairs_nx.obj",
|
"gui_model": "stairs_nx.obj",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_NONE,
|
||||||
"voxels": [6],
|
"voxels": ["stairs_nx"],
|
||||||
"transparent": false
|
"transparent": false
|
||||||
})
|
})
|
||||||
_create_block({
|
_create_block({
|
||||||
"name": "tall_grass",
|
"name": "tall_grass",
|
||||||
"gui_model": "tall_grass.obj",
|
"gui_model": "tall_grass.obj",
|
||||||
"rotation_type": ROTATION_TYPE_NONE,
|
"rotation_type": ROTATION_TYPE_NONE,
|
||||||
"voxels": [8],
|
"voxels": ["tall_grass"],
|
||||||
"transparent": true,
|
"transparent": true,
|
||||||
"backface_culling": false
|
"backface_culling": false
|
||||||
})
|
})
|
||||||
|
@ -98,6 +98,14 @@ func _create_block(params: Dictionary):
|
||||||
"backface_culling": true,
|
"backface_culling": true,
|
||||||
"directory": params.name
|
"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()
|
var block = Block.new()
|
||||||
block.id = len(_blocks)
|
block.id = len(_blocks)
|
||||||
|
@ -114,7 +122,7 @@ func _create_block(params: Dictionary):
|
||||||
_blocks.append(block)
|
_blocks.append(block)
|
||||||
|
|
||||||
|
|
||||||
func _defaults(d, defaults):
|
static func _defaults(d, defaults):
|
||||||
for k in defaults:
|
for k in defaults:
|
||||||
if not d.has(k):
|
if not d.has(k):
|
||||||
d[k] = defaults[k]
|
d[k] = defaults[k]
|
||||||
|
|
|
@ -20,30 +20,30 @@ collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||||
|
|
||||||
[sub_resource type="Voxel" id=3]
|
[sub_resource type="Voxel" id=3]
|
||||||
voxel_name = "grass"
|
voxel_name = "grass"
|
||||||
|
random_tickable = true
|
||||||
geometry_type = 2
|
geometry_type = 2
|
||||||
custom_mesh = ExtResource( 1 )
|
custom_mesh = ExtResource( 1 )
|
||||||
random_tickable = true
|
|
||||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||||
|
|
||||||
[sub_resource type="Voxel" id=4]
|
[sub_resource type="Voxel" id=4]
|
||||||
voxel_name = "log_x"
|
voxel_name = "log_x"
|
||||||
|
random_tickable = true
|
||||||
geometry_type = 2
|
geometry_type = 2
|
||||||
custom_mesh = ExtResource( 4 )
|
custom_mesh = ExtResource( 4 )
|
||||||
random_tickable = true
|
|
||||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||||
|
|
||||||
[sub_resource type="Voxel" id=5]
|
[sub_resource type="Voxel" id=5]
|
||||||
voxel_name = "log_y"
|
voxel_name = "log_y"
|
||||||
|
random_tickable = true
|
||||||
geometry_type = 2
|
geometry_type = 2
|
||||||
custom_mesh = ExtResource( 3 )
|
custom_mesh = ExtResource( 3 )
|
||||||
random_tickable = true
|
|
||||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||||
|
|
||||||
[sub_resource type="Voxel" id=6]
|
[sub_resource type="Voxel" id=6]
|
||||||
voxel_name = "log_z"
|
voxel_name = "log_z"
|
||||||
|
random_tickable = true
|
||||||
geometry_type = 2
|
geometry_type = 2
|
||||||
custom_mesh = ExtResource( 5 )
|
custom_mesh = ExtResource( 5 )
|
||||||
random_tickable = true
|
|
||||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||||
|
|
||||||
[sub_resource type="Voxel" id=7]
|
[sub_resource type="Voxel" id=7]
|
||||||
|
|
|
@ -21,7 +21,7 @@ export(NodePath) var terrain_path = null
|
||||||
export(Material) var cursor_material = null
|
export(Material) var cursor_material = null
|
||||||
|
|
||||||
# TODO Eventually invert these dependencies
|
# 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")
|
onready var _hotbar = get_node("../HotBar")
|
||||||
|
|
||||||
var _terrain = null
|
var _terrain = null
|
||||||
|
@ -50,7 +50,7 @@ func _ready():
|
||||||
_terrain_tool = _terrain.get_voxel_tool()
|
_terrain_tool = _terrain.get_voxel_tool()
|
||||||
|
|
||||||
|
|
||||||
func get_pointed_voxel():
|
func _get_pointed_voxel():
|
||||||
var origin = _head.get_global_transform().origin
|
var origin = _head.get_global_transform().origin
|
||||||
var forward = -_head.get_transform().basis.z.normalized()
|
var forward = -_head.get_transform().basis.z.normalized()
|
||||||
var hit = _terrain_tool.raycast(origin, forward, 10)
|
var hit = _terrain_tool.raycast(origin, forward, 10)
|
||||||
|
@ -61,7 +61,7 @@ func _physics_process(delta):
|
||||||
if _terrain == null:
|
if _terrain == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
var hit = get_pointed_voxel()
|
var hit = _get_pointed_voxel()
|
||||||
if hit != null:
|
if hit != null:
|
||||||
_cursor.show()
|
_cursor.show()
|
||||||
_cursor.set_translation(hit.position)
|
_cursor.set_translation(hit.position)
|
||||||
|
@ -82,7 +82,7 @@ func _physics_process(delta):
|
||||||
var pos = hit.previous_position
|
var pos = hit.previous_position
|
||||||
if has_cube == false:
|
if has_cube == false:
|
||||||
pos = hit.position
|
pos = hit.position
|
||||||
if can_place_voxel_at(pos):
|
if _can_place_voxel_at(pos):
|
||||||
var block_id = _hotbar.get_selected_block_type()
|
var block_id = _hotbar.get_selected_block_type()
|
||||||
if block_id != -1:
|
if block_id != -1:
|
||||||
_place_single_block(pos, block_id)
|
_place_single_block(pos, block_id)
|
||||||
|
@ -110,7 +110,8 @@ func _unhandled_input(event):
|
||||||
_hotbar.select_slot(slot_index)
|
_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 space_state = get_viewport().get_world().get_direct_space_state()
|
||||||
var params = PhysicsShapeQueryParameters.new()
|
var params = PhysicsShapeQueryParameters.new()
|
||||||
params.collision_mask = COLLISION_LAYER_AVATAR
|
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):
|
func _place_single_block(pos: Vector3, block_id: int):
|
||||||
var block = Blocks.get_block(block_id)
|
var block := Blocks.get_block(block_id)
|
||||||
var voxel_id = block.voxels[0]
|
var voxel_id := 0
|
||||||
# TODO Handle rotated variants etc
|
|
||||||
|
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)
|
_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.channel = VoxelBuffer.CHANNEL_TYPE
|
||||||
_terrain_tool.value = type
|
_terrain_tool.value = type
|
||||||
_terrain_tool.do_point(pos)
|
_terrain_tool.do_point(pos)
|
||||||
|
|
|
@ -84,3 +84,14 @@ static func get_triangle_normal(a: Vector3, b: Vector3, c: Vector3) -> Vector3:
|
||||||
var v = (a - c).normalized()
|
var v = (a - c).normalized()
|
||||||
return v.cross(u)
|
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue