Bases de Transform

Cinq boîtes et cinq Transform3D écrits à la main : identité, origine, Basis tournée, Basis mise à l'échelle et les trois combinés. Un fantôme marque où se trouve l'identité.

L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.

Classes Godot utilisées

Transform3DBasisMeshInstance3D

Le code

scripts/main.gd
extends Node

const STEPS: Array[String] = ['IDENTITY', 'origin', 'Basis rotated', 'Basis scaled', 'all three']
const SPACING: float = 3.2
const SIZE: float = 1.3

var boxes: Array[MeshInstance3D] = []
var elapsed: float = 0.0


func _ready() -> void:
	_add_environment()
	_add_light()
	_add_ground()

	for i in STEPS.size():
		var slot: Node3D = Node3D.new()
		slot.position = Vector3((i - 2) * SPACING, 1.0, 0)
		add_child(slot)

		slot.add_child(_make_ghost())

		var box: MeshInstance3D = _make_box(float(i) / STEPS.size())
		slot.add_child(box)
		boxes.append(box)

		_add_label(STEPS[i], slot.position + Vector3(0, -1.4, 0))

	var camera: Camera3D = Camera3D.new()
	camera.fov = 52.0
	camera.position = Vector3(0, 2.2, 11.5)
	add_child(camera)
	camera.look_at(Vector3(0, 1.3, 0), Vector3.UP)
	camera.current = true

	_apply()

	print('every box gets a Transform3D written by hand, and the wire ghost marks where IDENTITY sits')


func _process(delta: float) -> void:
	elapsed += delta
	_apply()


func _apply() -> void:
	var turn: float = elapsed * 0.55
	var lift: float = 0.9 + sin(elapsed * 1.6) * 0.6
	var pulse: float = 1.0 + cos(elapsed * 1.5) * 0.38

	boxes[0].transform = Transform3D.IDENTITY
	boxes[1].transform = Transform3D(Basis.IDENTITY, Vector3(0, lift, 0))
	boxes[2].transform = Transform3D(Basis(Vector3.UP, turn), Vector3.ZERO)
	boxes[3].transform = Transform3D(Basis.from_scale(Vector3(pulse, 1.0, pulse)), Vector3.ZERO)
	# Basis.scaled premultiplies, so a non uniform scale after a rotation comes out sheared
	boxes[4].transform = Transform3D(Basis(Vector3.UP, turn).scaled(Vector3(pulse, pulse, pulse)), Vector3(0, lift, 0))


func _make_box(hue: float) -> MeshInstance3D:
	var mesh: BoxMesh = BoxMesh.new()
	mesh.size = Vector3(SIZE, SIZE, SIZE)

	var material: StandardMaterial3D = StandardMaterial3D.new()
	material.albedo_color = Color.from_hsv(hue * 0.45 + 0.08, 0.5, 0.95)
	material.roughness = 0.4

	var box: MeshInstance3D = MeshInstance3D.new()
	box.mesh = mesh
	box.material_override = material

	return box


func _make_ghost() -> MeshInstance3D:
	var mesh: BoxMesh = BoxMesh.new()
	mesh.size = Vector3(SIZE, SIZE, SIZE) * 1.01

	var material: StandardMaterial3D = StandardMaterial3D.new()
	material.albedo_color = Color(0.6, 0.68, 0.9, 0.14)
	material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
	material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
	material.cull_mode = BaseMaterial3D.CULL_FRONT

	var ghost: MeshInstance3D = MeshInstance3D.new()
	ghost.mesh = mesh
	ghost.material_override = material

	return ghost


func _add_label(text: String, at: Vector3) -> void:
	var label: Label3D = Label3D.new()
	label.text = text
	label.font_size = 56
	label.pixel_size = 0.006
	label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
	label.alpha_cut = Label3D.ALPHA_CUT_DISCARD
	label.modulate = Color('#c8ccd8')
	label.outline_size = 14
	label.outline_modulate = Color(0, 0, 0, 0.9)
	label.position = at
	add_child(label)


func _add_ground() -> void:
	var mesh: PlaneMesh = PlaneMesh.new()
	mesh.size = Vector2(400, 400)

	var material: StandardMaterial3D = StandardMaterial3D.new()
	material.albedo_color = Color('#242938')
	material.roughness = 0.95

	var ground: MeshInstance3D = MeshInstance3D.new()
	ground.mesh = mesh
	ground.material_override = material
	ground.position = Vector3(0, -0.6, 0)
	add_child(ground)


func _add_environment() -> void:
	var sky_material: ProceduralSkyMaterial = ProceduralSkyMaterial.new()
	sky_material.sky_top_color = Color(0.06, 0.08, 0.16)
	sky_material.sky_horizon_color = Color(0.22, 0.25, 0.36)
	sky_material.ground_bottom_color = Color(0.15, 0.17, 0.23)
	sky_material.ground_horizon_color = Color(0.16, 0.18, 0.25)

	var sky: Sky = Sky.new()
	sky.sky_material = sky_material

	var env: Environment = Environment.new()
	env.background_mode = Environment.BG_SKY
	env.sky = sky
	env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
	env.ambient_light_energy = 0.9

	var world: WorldEnvironment = WorldEnvironment.new()
	world.environment = env
	add_child(world)


func _add_light() -> void:
	var light: DirectionalLight3D = DirectionalLight3D.new()
	light.rotation_degrees = Vector3(-52, -38, 0)
	light.light_energy = 1.3
	add_child(light)

Plus d'exemples de Scène 3D