Rock Generator 2.10.0: Quader als Grundform (Platten und Riegel)
Auf Wunsch des Users neben Wuerfel und Ico-Sphere eine Quader-Grundform mit frei einstellbaren Proportionen (X/Y/Z) plus Streuung je Stein. Damit entstehen flache Platten und langgestreckte Riegel - passt besonders zum Plattenlook der Genshin-Referenz, wo Felsen aus flachen Schichten bestehen. Wichtiges Detail: die Proportionen werden auf die MESH-DATEN angewendet (transform_apply), nicht auf das Objekt. Der Displace arbeitet mit globalen Texturkoordinaten - eine Objekt-Skalierung wuerde das Rauschen mitverzerren statt die Form zu aendern. Gemessen bei Proportion (2.0, 1.5, 0.35): 3.43 / 2.56 / 0.79 m (Z = 23 % von X), bei (2.2, 0.8, 0.9): 3.81 / 1.40 / 1.60 m. Der Zufalls-Button kennt die neue Form ebenfalls. Neuer Test tests/test_base_shapes.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
bl_info = {
|
||||
"name": "Stylized Rock Generator",
|
||||
"author": "D4rkst3r",
|
||||
"version": (2, 9, 0),
|
||||
"version": (2, 10, 0),
|
||||
"blender": (4, 2, 0),
|
||||
"location": "View3D > Sidebar > Rock Gen",
|
||||
"description": (
|
||||
@@ -50,7 +50,7 @@ CLASS_SIZES = {'S': 0.45, 'M': 1.0, 'L': 1.9, 'XL': 3.2}
|
||||
|
||||
# Property-Keys, die von Presets gespeichert/geladen werden.
|
||||
PRESET_KEYS = (
|
||||
"base_shape", "subsurf_levels", "texture_type", "noise_scale",
|
||||
"base_shape", "box_proportions", "box_variation", "subsurf_levels", "texture_type", "noise_scale",
|
||||
"displace_strength", "seed", "decimate_ratio_1", "decimate_ratio_2",
|
||||
"dissolve_angle", "generate_uv0", "generate_lightmap_uv",
|
||||
"randomize_transform", "scale_min", "scale_max",
|
||||
@@ -303,8 +303,24 @@ def _make_lightmap_uv(context, obj):
|
||||
def _build_rock_mesh(context, settings, index, location, rng, name=None):
|
||||
"""Baut das reine Rock-Mesh (ohne Transform/Material). Kann RockGenError werfen."""
|
||||
# 1. Basis-Mesh
|
||||
if settings.base_shape == 'CUBE':
|
||||
if settings.base_shape in ('CUBE', 'BOX'):
|
||||
bpy.ops.mesh.primitive_cube_add(size=2, location=location)
|
||||
if settings.base_shape == 'BOX':
|
||||
# Proportionen auf die MESH-DATEN anwenden, nicht auf das Objekt:
|
||||
# der Displace nutzt globale Texturkoordinaten, eine Objekt-Skalierung
|
||||
# wuerde das Rauschen mitverzerren statt die Form zu aendern.
|
||||
px, py, pz = settings.box_proportions
|
||||
v = settings.box_variation
|
||||
if v > 0.0:
|
||||
px *= 1.0 + rng.uniform(-v, v) * 0.5
|
||||
py *= 1.0 + rng.uniform(-v, v) * 0.5
|
||||
pz *= 1.0 + rng.uniform(-v, v) * 0.5
|
||||
ob_tmp = context.active_object
|
||||
ob_tmp.scale = (px, py, pz)
|
||||
_deselect_all(context)
|
||||
context.view_layer.objects.active = ob_tmp
|
||||
ob_tmp.select_set(True)
|
||||
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
|
||||
else:
|
||||
bpy.ops.mesh.primitive_ico_sphere_add(
|
||||
subdivisions=1, radius=1.0, location=location
|
||||
@@ -727,9 +743,24 @@ class RockGenSettings(PropertyGroup):
|
||||
# --- Basis ---
|
||||
base_shape: EnumProperty(
|
||||
name="Basis-Form",
|
||||
items=[('CUBE', "Cube", ""), ('ICOSPHERE', "Ico-Sphere", "")],
|
||||
items=[
|
||||
('CUBE', "Wuerfel", "Gleichmaessiger Brocken"),
|
||||
('BOX', "Quader", "Laengliche oder flache Grundform - Proportionen unten"),
|
||||
('ICOSPHERE', "Ico-Sphere", "Rundlicher Brocken"),
|
||||
],
|
||||
default='CUBE',
|
||||
)
|
||||
box_proportions: FloatVectorProperty(
|
||||
name="Quader-Proportionen", size=3, default=(1.6, 1.1, 0.55),
|
||||
min=0.15, max=4.0, subtype='XYZ',
|
||||
description=("Seitenverhaeltnis der Grundform bei 'Quader'. Flach (kleines Z) "
|
||||
"ergibt Platten und Findlinge, langgestreckt ergibt Brocken. "
|
||||
"Wird VOR dem Displace angewendet, damit die Verformung mitgeht"),
|
||||
)
|
||||
box_variation: FloatProperty(
|
||||
name="Proportions-Streuung", default=0.25, min=0.0, max=1.0,
|
||||
description="Wuerfelt die Proportionen je Stein etwas anders (0 = alle gleich)",
|
||||
)
|
||||
subsurf_levels: IntProperty(name="Subsurf Levels", default=5, min=1, max=6)
|
||||
|
||||
# --- Noise / Displace ---
|
||||
@@ -1501,7 +1532,7 @@ class ROCKGEN_OT_randomize(Operator):
|
||||
jitter("noise_scale_max", 0.6, 4.0)
|
||||
jitter("displace_strength_max", 0.2, 0.9)
|
||||
if s.random_shape:
|
||||
s.base_shape = rng.choice(['CUBE', 'ICOSPHERE'])
|
||||
s.base_shape = rng.choice(['CUBE', 'BOX', 'ICOSPHERE'])
|
||||
s.texture_type = rng.choice(['VORONOI', 'CLOUDS', 'DISTORTED_NOISE'])
|
||||
self.report({'INFO'}, "Neue Zufallswerte (Seed %d)." % s.seed)
|
||||
return {'FINISHED'}
|
||||
@@ -1626,6 +1657,9 @@ class VIEW3D_PT_rock_generator(Panel):
|
||||
box = layout.box()
|
||||
box.label(text="Basis")
|
||||
box.prop(settings, "base_shape")
|
||||
if settings.base_shape == 'BOX':
|
||||
box.prop(settings, "box_proportions")
|
||||
box.prop(settings, "box_variation")
|
||||
box.prop(settings, "subsurf_levels")
|
||||
|
||||
box = layout.box()
|
||||
|
||||
Reference in New Issue
Block a user