Moved wirecube cursor creation to utility script
parent
63c18a8883
commit
377b30ae69
|
@ -1,177 +1,129 @@
|
|||
extends Node
|
||||
|
||||
const COLLISION_LAYER_AVATAR = 2
|
||||
|
||||
export(NodePath) var terrain_path = null
|
||||
export(Material) var cursor_material = null
|
||||
|
||||
onready var _light = get_node("../../DirectionalLight") # For debug shadow toggle
|
||||
onready var _head = get_parent().get_node("Camera")
|
||||
|
||||
var _terrain = null
|
||||
var _terrain_tool = null
|
||||
var _cursor = null
|
||||
var _action_place = false
|
||||
var _action_remove = false
|
||||
|
||||
var _inventory = [1, 2]
|
||||
var _inventory_index = 0
|
||||
|
||||
|
||||
func _ready():
|
||||
if terrain_path == null:
|
||||
_terrain = get_parent().get_node(get_parent().terrain)
|
||||
terrain_path = _terrain.get_path() # For correctness
|
||||
else:
|
||||
_terrain = get_node(terrain_path)
|
||||
_cursor = _make_cursor()
|
||||
_terrain.add_child(_cursor)
|
||||
_terrain_tool = _terrain.get_voxel_tool()
|
||||
|
||||
|
||||
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)
|
||||
return hit
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
if _terrain == null:
|
||||
return
|
||||
|
||||
var hit = get_pointed_voxel()
|
||||
if hit != null:
|
||||
_cursor.show()
|
||||
_cursor.set_translation(hit.position + Vector3(1,1,1)*0.5)
|
||||
get_parent().get_node("debug_label").text = str(hit.position)
|
||||
else:
|
||||
_cursor.hide()
|
||||
get_parent().get_node("debug_label").text = "---"
|
||||
|
||||
# These inputs have to be in _fixed_process because they rely on collision queries
|
||||
if hit != null:
|
||||
var has_cube = _terrain_tool.get_voxel(hit.position) != 0
|
||||
|
||||
if _action_place and has_cube:
|
||||
var pos = hit.position
|
||||
do_sphere(pos, 5, 0)
|
||||
|
||||
elif _action_remove:
|
||||
var pos = hit.previous_position
|
||||
if has_cube == false:
|
||||
pos = hit.position
|
||||
if can_place_voxel_at(pos):
|
||||
do_sphere(pos, 4, _inventory[_inventory_index])
|
||||
print("Place voxel at ", pos)
|
||||
else:
|
||||
print("Can't place here!")
|
||||
|
||||
_action_place = false
|
||||
_action_remove = false
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.pressed:
|
||||
match event.button_index:
|
||||
BUTTON_LEFT:
|
||||
_action_place = true
|
||||
BUTTON_RIGHT:
|
||||
_action_remove = true
|
||||
|
||||
elif event is InputEventKey:
|
||||
if event.pressed:
|
||||
match event.scancode:
|
||||
KEY_1:
|
||||
select_inventory(0)
|
||||
KEY_2:
|
||||
select_inventory(1)
|
||||
KEY_L:
|
||||
_light.shadow_enabled = not _light.shadow_enabled
|
||||
|
||||
|
||||
func select_inventory(i):
|
||||
if i < 0 or i >= len(_inventory):
|
||||
return
|
||||
_inventory_index = i
|
||||
var vi = _inventory[i]
|
||||
print("Inventory select ", _terrain.voxel_library.get_voxel(vi).voxel_name, " (", vi, ")")
|
||||
|
||||
|
||||
func can_place_voxel_at(pos):
|
||||
var space_state = get_viewport().get_world().get_direct_space_state()
|
||||
var params = PhysicsShapeQueryParameters.new()
|
||||
params.collision_mask = COLLISION_LAYER_AVATAR
|
||||
params.transform = Transform(Basis(), pos + Vector3(1,1,1)*0.5)
|
||||
var shape = BoxShape.new()
|
||||
var ex = 0.5
|
||||
shape.extents = Vector3(ex, ex, ex)
|
||||
params.set_shape(shape)
|
||||
var hits = space_state.intersect_shape(params)
|
||||
return hits.size() == 0
|
||||
|
||||
|
||||
# Makes a 3D wireframe cube cursor
|
||||
func _make_cursor():
|
||||
var st = SurfaceTool.new()
|
||||
st.begin(Mesh.PRIMITIVE_LINES)
|
||||
_add_wireframe_cube(st, -Vector3(1,1,1)*0.5, 1, Color(0,0,0))
|
||||
var mesh = st.commit()
|
||||
var mesh_instance = MeshInstance.new()
|
||||
mesh_instance.mesh = mesh
|
||||
if cursor_material != null:
|
||||
mesh_instance.material_override = cursor_material
|
||||
mesh_instance.set_scale(Vector3(1,1,1)*1.01)
|
||||
return mesh_instance
|
||||
|
||||
|
||||
func do_sphere(center, r, type):
|
||||
_terrain_tool.channel = VoxelBuffer.CHANNEL_TYPE
|
||||
_terrain_tool.value = type
|
||||
#_terrain_tool.do_sphere(center, r)
|
||||
_terrain_tool.do_point(center)
|
||||
|
||||
|
||||
static func _add_wireframe_cube(st, pos, step, color):
|
||||
|
||||
st.add_color(color)
|
||||
|
||||
st.add_vertex(pos)
|
||||
st.add_vertex(pos + Vector3(step, 0, 0))
|
||||
|
||||
st.add_vertex(pos + Vector3(step, 0, 0))
|
||||
st.add_vertex(pos + Vector3(step, 0, step))
|
||||
|
||||
st.add_vertex(pos + Vector3(step, 0, step))
|
||||
st.add_vertex(pos + Vector3(0, 0, step))
|
||||
|
||||
st.add_vertex(pos + Vector3(0, 0, step))
|
||||
st.add_vertex(pos)
|
||||
|
||||
|
||||
st.add_vertex(pos + Vector3(0, step, 0))
|
||||
st.add_vertex(pos + Vector3(step, step, 0))
|
||||
|
||||
st.add_vertex(pos + Vector3(step, step, 0))
|
||||
st.add_vertex(pos + Vector3(step, step, step))
|
||||
|
||||
st.add_vertex(pos + Vector3(step, step, step))
|
||||
st.add_vertex(pos + Vector3(0, step, step))
|
||||
|
||||
st.add_vertex(pos + Vector3(0, step, step))
|
||||
st.add_vertex(pos + Vector3(0, step, 0))
|
||||
|
||||
|
||||
st.add_vertex(pos)
|
||||
st.add_vertex(pos + Vector3(0, step, 0))
|
||||
|
||||
st.add_vertex(pos + Vector3(step, 0, 0))
|
||||
st.add_vertex(pos + Vector3(step, step, 0))
|
||||
|
||||
st.add_vertex(pos + Vector3(step, 0, step))
|
||||
st.add_vertex(pos + Vector3(step, step, step))
|
||||
|
||||
st.add_vertex(pos + Vector3(0, 0, step))
|
||||
st.add_vertex(pos + Vector3(0, step, step))
|
||||
|
||||
extends Node
|
||||
|
||||
const Util = preload("res://common/util.gd")
|
||||
|
||||
const COLLISION_LAYER_AVATAR = 2
|
||||
|
||||
export(NodePath) var terrain_path = null
|
||||
export(Material) var cursor_material = null
|
||||
|
||||
onready var _light = get_node("../../DirectionalLight") # For debug shadow toggle
|
||||
onready var _head = get_parent().get_node("Camera")
|
||||
|
||||
var _terrain = null
|
||||
var _terrain_tool = null
|
||||
var _cursor = null
|
||||
var _action_place = false
|
||||
var _action_remove = false
|
||||
|
||||
var _inventory = [1, 2]
|
||||
var _inventory_index = 0
|
||||
|
||||
|
||||
func _ready():
|
||||
if terrain_path == null:
|
||||
_terrain = get_parent().get_node(get_parent().terrain)
|
||||
terrain_path = _terrain.get_path() # For correctness
|
||||
else:
|
||||
_terrain = get_node(terrain_path)
|
||||
|
||||
var mesh = Util.create_wirecube_mesh(Color(0,0,0))
|
||||
var mesh_instance = MeshInstance.new()
|
||||
mesh_instance.mesh = mesh
|
||||
if cursor_material != null:
|
||||
mesh_instance.material_override = cursor_material
|
||||
mesh_instance.set_scale(Vector3(1,1,1)*1.01)
|
||||
_cursor = mesh_instance
|
||||
|
||||
_terrain.add_child(_cursor)
|
||||
_terrain_tool = _terrain.get_voxel_tool()
|
||||
|
||||
|
||||
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)
|
||||
return hit
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
if _terrain == null:
|
||||
return
|
||||
|
||||
var hit = get_pointed_voxel()
|
||||
if hit != null:
|
||||
_cursor.show()
|
||||
_cursor.set_translation(hit.position)
|
||||
get_parent().get_node("debug_label").text = str(hit.position)
|
||||
else:
|
||||
_cursor.hide()
|
||||
get_parent().get_node("debug_label").text = "---"
|
||||
|
||||
# These inputs have to be in _fixed_process because they rely on collision queries
|
||||
if hit != null:
|
||||
var has_cube = _terrain_tool.get_voxel(hit.position) != 0
|
||||
|
||||
if _action_place and has_cube:
|
||||
var pos = hit.position
|
||||
do_sphere(pos, 5, 0)
|
||||
|
||||
elif _action_remove:
|
||||
var pos = hit.previous_position
|
||||
if has_cube == false:
|
||||
pos = hit.position
|
||||
if can_place_voxel_at(pos):
|
||||
do_sphere(pos, 4, _inventory[_inventory_index])
|
||||
print("Place voxel at ", pos)
|
||||
else:
|
||||
print("Can't place here!")
|
||||
|
||||
_action_place = false
|
||||
_action_remove = false
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.pressed:
|
||||
match event.button_index:
|
||||
BUTTON_LEFT:
|
||||
_action_place = true
|
||||
BUTTON_RIGHT:
|
||||
_action_remove = true
|
||||
|
||||
elif event is InputEventKey:
|
||||
if event.pressed:
|
||||
match event.scancode:
|
||||
KEY_1:
|
||||
select_inventory(0)
|
||||
KEY_2:
|
||||
select_inventory(1)
|
||||
KEY_L:
|
||||
_light.shadow_enabled = not _light.shadow_enabled
|
||||
|
||||
|
||||
func select_inventory(i):
|
||||
if i < 0 or i >= len(_inventory):
|
||||
return
|
||||
_inventory_index = i
|
||||
var vi = _inventory[i]
|
||||
print("Inventory select ", _terrain.voxel_library.get_voxel(vi).voxel_name, " (", vi, ")")
|
||||
|
||||
|
||||
func can_place_voxel_at(pos):
|
||||
var space_state = get_viewport().get_world().get_direct_space_state()
|
||||
var params = PhysicsShapeQueryParameters.new()
|
||||
params.collision_mask = COLLISION_LAYER_AVATAR
|
||||
params.transform = Transform(Basis(), pos + Vector3(1,1,1)*0.5)
|
||||
var shape = BoxShape.new()
|
||||
var ex = 0.5
|
||||
shape.extents = Vector3(ex, ex, ex)
|
||||
params.set_shape(shape)
|
||||
var hits = space_state.intersect_shape(params)
|
||||
return hits.size() == 0
|
||||
|
||||
|
||||
func do_sphere(center, r, type):
|
||||
_terrain_tool.channel = VoxelBuffer.CHANNEL_TYPE
|
||||
_terrain_tool.value = type
|
||||
_terrain_tool.do_point(center)
|
||||
|
||||
|
|
|
@ -1,80 +1,61 @@
|
|||
extends Spatial
|
||||
|
||||
export var speed = 5.0
|
||||
export var gravity = 9.8
|
||||
export var jump_force = 5.0
|
||||
export(NodePath) var head = null
|
||||
|
||||
# Not used in this script, but might be useful for child nodes because
|
||||
# this controller will most likely be on the root
|
||||
export(NodePath) var terrain = null
|
||||
|
||||
var _velocity = Vector3()
|
||||
var _grounded = false
|
||||
var _head = null
|
||||
var _box_mover = VoxelBoxMover.new()
|
||||
|
||||
|
||||
func _ready():
|
||||
_head = get_node(head)
|
||||
|
||||
# FIX
|
||||
#set_shape_transform(0, Transform().rotated(Vector3(1,0,0), PI/2.0))
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
var forward = _head.get_transform().basis.z.normalized()
|
||||
forward = Plane(Vector3(0, 1, 0), 0).project(forward)
|
||||
var right = _head.get_transform().basis.x.normalized()
|
||||
var motor = Vector3()
|
||||
|
||||
if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_Z) or Input.is_key_pressed(KEY_W):
|
||||
motor -= forward
|
||||
if Input.is_key_pressed(KEY_DOWN) or Input.is_key_pressed(KEY_S):
|
||||
motor += forward
|
||||
if Input.is_key_pressed(KEY_LEFT) or Input.is_key_pressed(KEY_Q) or Input.is_key_pressed(KEY_A):
|
||||
motor -= right
|
||||
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
||||
motor += right
|
||||
|
||||
motor = motor.normalized() * speed
|
||||
|
||||
_velocity.x = motor.x
|
||||
_velocity.z = motor.z
|
||||
_velocity.y -= gravity * delta
|
||||
|
||||
#if _grounded and Input.is_key_pressed(KEY_SPACE):
|
||||
if Input.is_key_pressed(KEY_SPACE):
|
||||
_velocity.y = jump_force
|
||||
#_grounded = false
|
||||
|
||||
var motion = _velocity * delta
|
||||
|
||||
if has_node(terrain):
|
||||
var aabb = AABB(Vector3(-0.4, -0.9, -0.4), Vector3(0.8, 1.8, 0.8))
|
||||
var terrain_node = get_node(terrain)
|
||||
motion = _box_mover.get_motion(get_translation(), motion, aabb, terrain_node)
|
||||
global_translate(motion)
|
||||
|
||||
assert(delta > 0)
|
||||
_velocity = motion / delta
|
||||
|
||||
#var rem = move(motion)
|
||||
|
||||
# TODO Fix it, obsolete code
|
||||
# if is_colliding():
|
||||
# var n = get_collision_normal()
|
||||
# var k = 1.0#clamp(n.y, 0, 1)
|
||||
# rem = rem.slide(n)*k
|
||||
# _velocity = _velocity.slide(n)*k
|
||||
# #rem = n.slide(rem)*k
|
||||
# #_velocity = n.slide(_velocity)*k
|
||||
# _grounded = true
|
||||
# move(rem)
|
||||
# else:
|
||||
# _grounded = false
|
||||
#get_node("debug").set_text("Grounded=" + str(_grounded))
|
||||
|
||||
|
||||
|
||||
extends Spatial
|
||||
|
||||
export var speed = 5.0
|
||||
export var gravity = 9.8
|
||||
export var jump_force = 5.0
|
||||
export(NodePath) var head = null
|
||||
|
||||
# Not used in this script, but might be useful for child nodes because
|
||||
# this controller will most likely be on the root
|
||||
export(NodePath) var terrain = null
|
||||
|
||||
var _velocity = Vector3()
|
||||
var _grounded = false
|
||||
var _head = null
|
||||
var _box_mover = VoxelBoxMover.new()
|
||||
|
||||
|
||||
func _ready():
|
||||
_head = get_node(head)
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
var forward = _head.get_transform().basis.z.normalized()
|
||||
forward = Plane(Vector3(0, 1, 0), 0).project(forward)
|
||||
var right = _head.get_transform().basis.x.normalized()
|
||||
var motor = Vector3()
|
||||
|
||||
if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_Z) or Input.is_key_pressed(KEY_W):
|
||||
motor -= forward
|
||||
if Input.is_key_pressed(KEY_DOWN) or Input.is_key_pressed(KEY_S):
|
||||
motor += forward
|
||||
if Input.is_key_pressed(KEY_LEFT) or Input.is_key_pressed(KEY_Q) or Input.is_key_pressed(KEY_A):
|
||||
motor -= right
|
||||
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
||||
motor += right
|
||||
|
||||
motor = motor.normalized() * speed
|
||||
|
||||
_velocity.x = motor.x
|
||||
_velocity.z = motor.z
|
||||
_velocity.y -= gravity * delta
|
||||
|
||||
#if _grounded and Input.is_key_pressed(KEY_SPACE):
|
||||
if Input.is_key_pressed(KEY_SPACE):
|
||||
_velocity.y = jump_force
|
||||
#_grounded = false
|
||||
|
||||
var motion = _velocity * delta
|
||||
|
||||
if has_node(terrain):
|
||||
var aabb = AABB(Vector3(-0.4, -0.9, -0.4), Vector3(0.8, 1.8, 0.8))
|
||||
var terrain_node = get_node(terrain)
|
||||
motion = _box_mover.get_motion(get_translation(), motion, aabb, terrain_node)
|
||||
global_translate(motion)
|
||||
|
||||
assert(delta > 0)
|
||||
_velocity = motion / delta
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
[ext_resource path="res://blocky_terrain/profiling_gui.gd" type="Script" id=8]
|
||||
[ext_resource path="res://blocky_terrain/debug3d.gd" type="Script" id=9]
|
||||
|
||||
|
||||
|
||||
[sub_resource type="ProceduralSky" id=1]
|
||||
sky_top_color = Color( 0.268204, 0.522478, 0.847656, 1 )
|
||||
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
|
||||
|
@ -86,7 +84,6 @@ stream = ExtResource( 1 )
|
|||
voxel_library = SubResource( 6 )
|
||||
view_distance = 256
|
||||
viewer_path = NodePath("../CharacterAvatar")
|
||||
generate_collisions = true
|
||||
material/0 = ExtResource( 2 )
|
||||
material/1 = ExtResource( 3 )
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
static func create_wirecube_mesh(color = Color(1,1,1)):
|
||||
var positions = PoolVector3Array([
|
||||
Vector3(0, 0, 0),
|
||||
Vector3(1, 0, 0),
|
||||
Vector3(1, 0, 1),
|
||||
Vector3(0, 0, 1),
|
||||
Vector3(0, 1, 0),
|
||||
Vector3(1, 1, 0),
|
||||
Vector3(1, 1, 1),
|
||||
Vector3(0, 1, 1),
|
||||
])
|
||||
var colors = PoolColorArray([
|
||||
color, color, color, color,
|
||||
color, color, color, color,
|
||||
])
|
||||
var indices = PoolIntArray([
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
7, 4,
|
||||
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7
|
||||
])
|
||||
var arrays = []
|
||||
arrays.resize(Mesh.ARRAY_MAX)
|
||||
arrays[Mesh.ARRAY_VERTEX] = positions
|
||||
arrays[Mesh.ARRAY_COLOR] = colors
|
||||
arrays[Mesh.ARRAY_INDEX] = indices
|
||||
var mesh = ArrayMesh.new()
|
||||
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, arrays)
|
||||
return mesh
|
||||
|
Loading…
Reference in New Issue