MINI MERK, MAXI MERK (6 wheels), HARDON SHAGGEN panel van
New moke body style: open slab tub, no doors, exposed seats, windscreen, rip-off det_roof canopy on posts, optional extra visual axles (physics stays 4-ray). New van style: cargo box from cab to tail with det_tailgate. Smoke test ram made deterministic (re-aim loop instead of blind throttle). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
09c7b2b280
commit
9a4d96ae54
BIN
cars/hardon_shaggen/car.glb
Normal file
BIN
cars/hardon_shaggen/car.glb
Normal file
Binary file not shown.
42
cars/hardon_shaggen/car.glb.import
Normal file
42
cars/hardon_shaggen/car.glb.import
Normal file
@ -0,0 +1,42 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://bts43pvbjjekx"
|
||||
path="res://.godot/imported/car.glb-9f1ddebc9927c2e6e83490ea92684b71.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://cars/hardon_shaggen/car.glb"
|
||||
dest_files=["res://.godot/imported/car.glb-9f1ddebc9927c2e6e83490ea92684b71.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
13
cars/hardon_shaggen/stats.tres
Normal file
13
cars/hardon_shaggen/stats.tres
Normal file
@ -0,0 +1,13 @@
|
||||
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1")
|
||||
display_name = "HARDON SHAGGEN"
|
||||
model_path = "res://cars/hardon_shaggen/car.glb"
|
||||
engine_power = 14.0
|
||||
mass = 1250.0
|
||||
grip = 5.5
|
||||
length = 4.55
|
||||
width = 1.72
|
||||
BIN
cars/maxi_merk/car.glb
Normal file
BIN
cars/maxi_merk/car.glb
Normal file
Binary file not shown.
42
cars/maxi_merk/car.glb.import
Normal file
42
cars/maxi_merk/car.glb.import
Normal file
@ -0,0 +1,42 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://crnwobwv4cj48"
|
||||
path="res://.godot/imported/car.glb-79503cc654b181d9b94d035ccfa1cfaa.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://cars/maxi_merk/car.glb"
|
||||
dest_files=["res://.godot/imported/car.glb-79503cc654b181d9b94d035ccfa1cfaa.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
13
cars/maxi_merk/stats.tres
Normal file
13
cars/maxi_merk/stats.tres
Normal file
@ -0,0 +1,13 @@
|
||||
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1")
|
||||
display_name = "MAXI MERK"
|
||||
model_path = "res://cars/maxi_merk/car.glb"
|
||||
engine_power = 12.0
|
||||
mass = 800.0
|
||||
grip = 6.5
|
||||
length = 4.35
|
||||
width = 1.45
|
||||
BIN
cars/mini_merk/car.glb
Normal file
BIN
cars/mini_merk/car.glb
Normal file
Binary file not shown.
42
cars/mini_merk/car.glb.import
Normal file
42
cars/mini_merk/car.glb.import
Normal file
@ -0,0 +1,42 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://b8cnylnv16dt"
|
||||
path="res://.godot/imported/car.glb-6a6391a8dfa537986da8e39a8baed19e.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://cars/mini_merk/car.glb"
|
||||
dest_files=["res://.godot/imported/car.glb-6a6391a8dfa537986da8e39a8baed19e.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
13
cars/mini_merk/stats.tres
Normal file
13
cars/mini_merk/stats.tres
Normal file
@ -0,0 +1,13 @@
|
||||
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1")
|
||||
display_name = "MINI MERK"
|
||||
model_path = "res://cars/mini_merk/car.glb"
|
||||
engine_power = 9.0
|
||||
mass = 600.0
|
||||
grip = 7.5
|
||||
length = 3.05
|
||||
width = 1.42
|
||||
40
shot_datto_120y.png.import
Normal file
40
shot_datto_120y.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://csax7yqjgptvt"
|
||||
path="res://.godot/imported/shot_datto_120y.png-85e191822a21ddbb3112ee0a47028b7f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_datto_120y.png"
|
||||
dest_files=["res://.godot/imported/shot_datto_120y.png-85e191822a21ddbb3112ee0a47028b7f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_floored_xd.png.import
Normal file
40
shot_floored_xd.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cd5quvmmdk7wy"
|
||||
path="res://.godot/imported/shot_floored_xd.png-6498dca165edfeb647825ab5252ac5e1.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_floored_xd.png"
|
||||
dest_files=["res://.godot/imported/shot_floored_xd.png-6498dca165edfeb647825ab5252ac5e1.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_turdrunner_slur.png.import
Normal file
40
shot_turdrunner_slur.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bxit0l621tsok"
|
||||
path="res://.godot/imported/shot_turdrunner_slur.png-2dfbb7c644ee0226f53c86ea197285f9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_turdrunner_slur.png"
|
||||
dest_files=["res://.godot/imported/shot_turdrunner_slur.png-2dfbb7c644ee0226f53c86ea197285f9.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@ -38,13 +38,19 @@ func _run() -> void:
|
||||
assert(game.traffic.size() == Game.TRAFFIC_COUNT["crash"], "traffic missing")
|
||||
var victim: TrafficCar = game.traffic[0]
|
||||
await physics_frame # traffic takes position on its first physics tick
|
||||
game.car.global_position = victim.global_position - victim.global_basis.z * 15.0
|
||||
game.car.look_at(victim.global_position)
|
||||
Input.action_press("throttle")
|
||||
for i in 240:
|
||||
await physics_frame
|
||||
for attempt in 8: # re-aim: victim keeps moving along the loop
|
||||
if not victim.live:
|
||||
break
|
||||
var to_victim := (victim.global_position - game.car.global_position)
|
||||
game.car.global_position = victim.global_position - victim.global_basis.z * 8.0
|
||||
game.car.look_at(victim.global_position)
|
||||
to_victim = (victim.global_position - game.car.global_position).normalized()
|
||||
game.car.linear_velocity = to_victim * 18.0
|
||||
for i in 30:
|
||||
await physics_frame
|
||||
if not victim.live:
|
||||
break
|
||||
Input.action_release("throttle")
|
||||
assert(not victim.live, "rammed traffic never went dynamic")
|
||||
assert(game.score > 0.0, "crash mode scored nothing")
|
||||
|
||||
@ -67,6 +67,18 @@ CARS = {
|
||||
bonnet=0.95, boot=0.30, roof=1.36, roof_rear=0.95,
|
||||
ohang_f=0.78, ohang_r=0.70, wheel=0.27,
|
||||
paint=(0.10, 0.55, 0.52, 1), chrome_bumpers=False, hatch=True),
|
||||
"hardon_shaggen": dict(L=4.55, W=1.72, nose=0.66, belt=0.86, tail=0.84,
|
||||
bonnet=1.35, boot=2.05, roof=1.42, roof_rear=0.25,
|
||||
ohang_f=0.85, ohang_r=0.95, wheel=0.29,
|
||||
paint=(0.70, 0.72, 0.58, 1), chrome_bumpers=True, hatch=False,
|
||||
doors=2, van=True),
|
||||
# mokes use the open-tub builder: style="moke"
|
||||
"mini_merk": dict(style="moke", L=3.05, W=1.42, nose=0.60, tub=0.66, canopy=1.38,
|
||||
bonnet=0.85, ohang_f=0.55, ohang_r=0.55, wheel=0.26,
|
||||
paint=(0.95, 0.62, 0.72, 1)),
|
||||
"maxi_merk": dict(style="moke", L=4.35, W=1.45, nose=0.60, tub=0.66, canopy=1.38,
|
||||
bonnet=1.00, ohang_f=0.60, ohang_r=0.60, wheel=0.26,
|
||||
paint=(0.93, 0.78, 0.05, 1), extra_axles=[1.35], rear_bench=True),
|
||||
}
|
||||
|
||||
|
||||
@ -191,13 +203,19 @@ def build(car_id, s):
|
||||
parts.append(box("det_bumper_f", (0, f + 0.05, bottom + 0.16), (W + 0.06, 0.15, 0.16), bumper_mat))
|
||||
parts.append(box("det_bumper_r", (0, r - 0.05, bottom + 0.16), (W + 0.06, 0.15, 0.16), bumper_mat))
|
||||
|
||||
if s.get("van"): # cargo box from cab rear to tail, plus rip-off tailgate
|
||||
parts.append(box("van_box", (0, (boot_y + r) / 2, (s["belt"] + s["roof"]) / 2),
|
||||
(W * 0.94, boot_y - r - 0.05, s["roof"] - s["belt"]), paint))
|
||||
parts.append(box("det_tailgate", (0, r - 0.03, (s["belt"] + s["roof"]) / 2 - 0.04),
|
||||
(W * 0.72, 0.05, s["roof"] - s["belt"] - 0.22), paint_dk))
|
||||
|
||||
# bonnet plate follows the bonnet slope; optional two-tone accent colour
|
||||
bonnet_mat = material("bonnet", s["bonnet_color"], rough=0.35) if "bonnet_color" in s else paint_dk
|
||||
by1, bz1, by2, bz2 = f - 0.35, nose2, ws_base + 0.03, s["belt"]
|
||||
ang = math.atan2(bz2 - bz1, by2 - by1)
|
||||
parts.append(box("det_bonnet", ((0, (by1 + by2) / 2, (bz1 + bz2) / 2 + 0.02)),
|
||||
(W * 0.7, math.hypot(by2 - by1, bz2 - bz1) - 0.1, 0.04), bonnet_mat, rot_x=-ang))
|
||||
if not s["hatch"]:
|
||||
if not s["hatch"] and not s.get("van"):
|
||||
ty1, tz1, ty2, tz2 = boot_y - 0.03, s["belt"], r + 0.1, s["tail"]
|
||||
ang = math.atan2(tz2 - tz1, ty2 - ty1)
|
||||
parts.append(box("det_boot", ((0, (ty1 + ty2) / 2, (tz1 + tz2) / 2 + 0.02)),
|
||||
@ -236,6 +254,80 @@ def build(car_id, s):
|
||||
print("built", car_id, "->", path)
|
||||
|
||||
|
||||
def build_moke(car_id, s):
|
||||
"""Open-top Moke: slab tub, no doors, exposed seats, rip-off canopy."""
|
||||
wipe()
|
||||
paint = material("paint", s["paint"], rough=0.45)
|
||||
glass = material("glass", GLASS, rough=0.2)
|
||||
tyre = material("tyre", TYRE, rough=0.9)
|
||||
chrome = material("chrome", CHROME, metallic=1.0, rough=0.25)
|
||||
dark = material("dark", DARK, rough=0.8)
|
||||
canvas = material("canvas", (0.07, 0.07, 0.07, 1), rough=0.95)
|
||||
|
||||
L, W = s["L"], s["W"]
|
||||
f, r, hw = L / 2, -L / 2, W / 2
|
||||
bottom = 0.25
|
||||
tub = s["tub"]
|
||||
ws_base = f - s["bonnet"]
|
||||
|
||||
body = extrude_profile("body", [
|
||||
(f, bottom + 0.1), (f, s["nose"]), (f - 0.15, tub), (r + 0.05, tub),
|
||||
(r, s["nose"]), (r, bottom + 0.1), (r + 0.15, bottom), (f - 0.15, bottom),
|
||||
], hw, paint)
|
||||
|
||||
parts = [box("windscreen", (0, ws_base, tub + 0.26), (W * 0.88, 0.04, 0.5), glass, rot_x=0.12)]
|
||||
canopy_len = ws_base - r - 0.05
|
||||
parts.append(box("det_roof", (0, (ws_base + r) / 2, s["canopy"]), (W * 0.98, canopy_len, 0.06), canvas))
|
||||
for py in (ws_base, r + 0.15):
|
||||
for sx in (-1, 1):
|
||||
parts.append(box("post", (sx * (hw - 0.08), py, (tub + s["canopy"]) / 2),
|
||||
(0.05, 0.05, s["canopy"] - tub), dark))
|
||||
seats = [(ws_base - 0.55, -0.33), (ws_base - 0.55, 0.33)]
|
||||
if s.get("rear_bench"):
|
||||
seats += [(ws_base - 1.45, -0.33), (ws_base - 1.45, 0.33)]
|
||||
for i, (sy, sx) in enumerate(seats):
|
||||
parts.append(box("trim_seat%d" % i, (sx, sy, tub + 0.10), (0.45, 0.45, 0.22), dark))
|
||||
parts.append(box("trim_seatback%d" % i, (sx, sy - 0.22, tub + 0.32), (0.45, 0.08, 0.42), dark))
|
||||
for side, sx in (("l", -1), ("r", 1)):
|
||||
parts.append(box("det_mirror_%s" % side, (sx * (hw + 0.07), ws_base + 0.02, tub + 0.42),
|
||||
(0.12, 0.08, 0.12), dark))
|
||||
parts.append(box("det_bumper_f", (0, f + 0.05, bottom + 0.14), (W + 0.04, 0.13, 0.13), chrome))
|
||||
parts.append(box("det_bumper_r", (0, r - 0.05, bottom + 0.14), (W + 0.04, 0.13, 0.13), chrome))
|
||||
parts.append(box("det_bonnet", (0, (f - 0.12 + ws_base) / 2, tub + 0.015),
|
||||
(W * 0.6, f - 0.12 - ws_base - 0.05, 0.04), paint))
|
||||
|
||||
trim = [
|
||||
box("trim_grille", (0, f + 0.01, s["nose"] - 0.13), (W * 0.45, 0.05, 0.11), dark),
|
||||
box("trim_light_fl", (-W * 0.33, f + 0.02, s["nose"] - 0.12), (0.18, 0.05, 0.14), material("lf", LIGHT_F)),
|
||||
box("trim_light_fr", (W * 0.33, f + 0.02, s["nose"] - 0.12), (0.18, 0.05, 0.14), material("lf2", LIGHT_F)),
|
||||
box("trim_light_rl", (-W * 0.32, r - 0.02, s["nose"] - 0.12), (0.2, 0.05, 0.11), material("lr", LIGHT_R)),
|
||||
box("trim_light_rr", (W * 0.32, r - 0.02, s["nose"] - 0.12), (0.2, 0.05, 0.11), material("lr2", LIGHT_R)),
|
||||
]
|
||||
|
||||
ax_f, ax_r = f - s["ohang_f"], r + s["ohang_r"]
|
||||
wx = hw - 0.09
|
||||
axles = [ax_f, ax_r] + [r + e for e in s.get("extra_axles", [])]
|
||||
wheels = []
|
||||
for i, ay in enumerate(axles):
|
||||
wheels.append(wheel("wheel_%dl" % i, -wx, ay, s["wheel"], tyre))
|
||||
wheels.append(wheel("wheel_%dr" % i, wx, ay, s["wheel"], tyre))
|
||||
|
||||
for obj in parts + trim + wheels:
|
||||
obj.parent = body
|
||||
body.location.z = -0.75
|
||||
|
||||
out_dir = os.path.join(OUT, car_id)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
path = os.path.join(out_dir, "car.glb")
|
||||
for obj in bpy.data.objects:
|
||||
obj.select_set(True)
|
||||
bpy.ops.export_scene.gltf(filepath=path, export_format="GLB", use_selection=True)
|
||||
print("built", car_id, "->", path)
|
||||
|
||||
|
||||
for car_id, spec in CARS.items():
|
||||
build(car_id, spec)
|
||||
if spec.get("style") == "moke":
|
||||
build_moke(car_id, spec)
|
||||
else:
|
||||
build(car_id, spec)
|
||||
print("done: %d cars" % len(CARS))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user