Spaces:
Running on Zero
Running on Zero
File size: 4,714 Bytes
77e37fc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | from __future__ import annotations
import re
from dataclasses import dataclass, asdict
@dataclass
class PromptSpec:
object_type: str = "cargo_hauler"
scale: str = "small"
hull_style: str = "boxy"
engine_count: int = 2
wing_span: float = 0.2
cargo_ratio: float = 0.38
cockpit_ratio: float = 0.18
fin_height: float = 0.0
landing_gear: bool = True
asymmetry: float = 0.0
notes: str = ""
def to_dict(self) -> dict:
return asdict(self)
TYPE_KEYWORDS = {
"fighter": "fighter",
"combat": "fighter",
"interceptor": "fighter",
"shuttle": "shuttle",
"freighter": "freighter",
"hauler": "cargo_hauler",
"cargo": "cargo_hauler",
"transport": "cargo_hauler",
"dropship": "dropship",
"drone": "drone",
}
STYLE_KEYWORDS = {
"boxy": "boxy",
"industrial": "boxy",
"hard-surface": "boxy",
"rounded": "rounded",
"sleek": "sleek",
"streamlined": "sleek",
"brutalist": "boxy",
}
SCALE_KEYWORDS = {
"tiny": "small",
"small": "small",
"compact": "small",
"medium": "medium",
"mid-size": "medium",
"large": "large",
"heavy": "large",
"huge": "large",
}
VALID_OBJECT_TYPES = {"cargo_hauler", "fighter", "shuttle", "freighter", "dropship", "drone"}
VALID_SCALES = {"small", "medium", "large"}
VALID_HULL_STYLES = {"boxy", "rounded", "sleek"}
def _clamp(value: float, low: float, high: float) -> float:
return max(low, min(high, value))
def merge_prompt_specs(primary: PromptSpec, secondary: PromptSpec) -> PromptSpec:
merged = PromptSpec(**primary.to_dict())
if secondary.object_type in VALID_OBJECT_TYPES:
merged.object_type = secondary.object_type
if secondary.scale in VALID_SCALES:
merged.scale = secondary.scale
if secondary.hull_style in VALID_HULL_STYLES:
merged.hull_style = secondary.hull_style
merged.engine_count = int(_clamp(secondary.engine_count, 1, 6))
merged.wing_span = float(_clamp(secondary.wing_span, 0.0, 0.6))
merged.cargo_ratio = float(_clamp(secondary.cargo_ratio, 0.0, 0.65))
merged.cockpit_ratio = float(_clamp(secondary.cockpit_ratio, 0.10, 0.30))
merged.fin_height = float(_clamp(secondary.fin_height, 0.0, 0.3))
merged.landing_gear = bool(secondary.landing_gear)
merged.asymmetry = float(_clamp(secondary.asymmetry, 0.0, 0.2))
merged.notes = secondary.notes or primary.notes
if merged.object_type in {"fighter", "drone"}:
merged.cargo_ratio = min(merged.cargo_ratio, 0.20)
if merged.hull_style == "boxy":
merged.hull_style = "sleek"
return merged
def parse_prompt(prompt: str) -> PromptSpec:
text = prompt.lower().strip()
spec = PromptSpec(notes=prompt.strip())
for key, value in TYPE_KEYWORDS.items():
if key in text:
spec.object_type = value
break
for key, value in STYLE_KEYWORDS.items():
if key in text:
spec.hull_style = value
break
for key, value in SCALE_KEYWORDS.items():
if key in text:
spec.scale = value
break
if any(word in text for word in ["wing", "wings"]):
spec.wing_span = 0.42 if spec.object_type == "fighter" else 0.28
if any(word in text for word in ["no wings", "wingless"]):
spec.wing_span = 0.0
if any(word in text for word in ["cargo bay", "cargo hold", "container", "freight"]):
spec.cargo_ratio = 0.48
if any(word in text for word in ["big cockpit", "large cockpit", "glass nose"]):
spec.cockpit_ratio = 0.24
if any(word in text for word in ["small cockpit", "tiny cockpit"]):
spec.cockpit_ratio = 0.13
if any(word in text for word in ["fin", "tail", "vertical stabilizer"]):
spec.fin_height = 0.18 if spec.object_type != "fighter" else 0.12
if any(word in text for word in ["hover", "hovercraft", "antigrav"]):
spec.landing_gear = False
if spec.object_type in {"fighter", "drone"}:
spec.engine_count = 1 if "single engine" in text else 2
spec.cargo_ratio = min(spec.cargo_ratio, 0.18)
spec.hull_style = "sleek"
elif spec.object_type in {"cargo_hauler", "freighter", "dropship"}:
spec.engine_count = 4 if any(x in text for x in ["4 engine", "four engine", "quad engine"]) else 2
spec.hull_style = "boxy" if spec.hull_style == "sleek" else spec.hull_style
numeric_engine = re.search(r"(\d+)\s*(?:engine|engines)", text)
if numeric_engine:
spec.engine_count = max(1, min(6, int(numeric_engine.group(1))))
if any(word in text for word in ["asymmetric", "uneven", "offset"]):
spec.asymmetry = 0.12
return spec
|