184 lines
6.2 KiB
Python
184 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
INTEGRATED GRAVITY GENERATION + BACKGROUND REMOVAL
|
|
DolinaSmrti Asset Production Pipeline
|
|
"""
|
|
|
|
import os
|
|
import time
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
BASE_DIR = Path("/Users/davidkotnik/repos/novafarma")
|
|
ASSETS_DIR = BASE_DIR / "assets" / "images"
|
|
BRAIN_DIR = Path("/Users/davidkotnik/.gemini/antigravity/brain/97fc5700-8b7e-46b1-b80b-c003e42edd7e")
|
|
|
|
# Generate + Remove workflow
|
|
WORKFLOW_STEPS = """
|
|
WORKFLOW:
|
|
1. Generate image with Gravity (white background)
|
|
2. Copy to assets/images/[category]/
|
|
3. Run background removal (rembg)
|
|
4. Verify transparency
|
|
"""
|
|
|
|
# Updated style prompt for white background
|
|
STYLE_PROMPT = """
|
|
(bold black outlines:1.4), dark hand-drawn stylized indie game asset,
|
|
(gritty noir aesthetic:1.2), flat colors, muted color palette,
|
|
exaggerated features, warped perspective, wonky proportions,
|
|
mature post-apocalyptic vibe, Don't Starve inspired,
|
|
high contrast noir elements, isolated object centered on solid white background,
|
|
clean edges, simple composition, no shadows on ground, no environment elements
|
|
"""
|
|
|
|
# Buildings to generate (missing from assets)
|
|
BUILDINGS = [
|
|
"church_unfinished",
|
|
"workshop_complete", "workshop_ruined",
|
|
"barn_complete", "barn_damaged",
|
|
"farmhouse_complete", "farmhouse_ruined",
|
|
"store_complete", "store_damaged",
|
|
"windmill", "watchtower", "greenhouse",
|
|
"laboratory", "vape_lab", "furnace_building",
|
|
"mint_building", "tailoring_shop",
|
|
]
|
|
|
|
# Additional categories
|
|
WORKSTATIONS = [
|
|
"furnace", "campfire", "tailoring_table",
|
|
"vape_lab_station", "mint_station",
|
|
"basic_sprinkler", "quality_sprinkler", "iridium_sprinkler",
|
|
]
|
|
|
|
BOSSES = [
|
|
"mutant_king", "zombie_horde_leader", "ancient_tree",
|
|
"giant_troll_king", "ice_titan", "fire_dragon",
|
|
"king_slime",
|
|
]
|
|
|
|
|
|
def generate_building_prompt(building_name: str) -> str:
|
|
"""Generate building-specific prompt"""
|
|
clean_name = building_name.replace("_", " ")
|
|
|
|
prompts = {
|
|
"church_unfinished": "unfinished church building under construction, stone church with scaffolding and missing walls",
|
|
"workshop_complete": "complete workshop building, craftsman work shed with tools visible",
|
|
"workshop_ruined": "ruined workshop building, destroyed shed with collapsed roof",
|
|
"barn_complete": "complete barn building, large wooden farm barn with hay loft",
|
|
"barn_damaged": "damaged barn building, weathered wooden barn with broken boards",
|
|
"farmhouse_complete": "complete farmhouse building, cozy two-story house with chimney",
|
|
"farmhouse_ruined": "ruined farmhouse building, collapsed house with broken walls",
|
|
"store_complete": "complete store building, merchant shop with windows and door",
|
|
"store_damaged": "damaged store building, broken shop with boarded windows",
|
|
"windmill": "windmill building, tall wooden windmill with rotating blades",
|
|
"watchtower": "watchtower building, tall stone tower with lookout platform",
|
|
"greenhouse": "greenhouse building, glass structure for growing plants",
|
|
"laboratory": "laboratory building, science research facility",
|
|
"vape_lab": "vape lab building, workshop for vape liquid production",
|
|
"furnace_building": "furnace building, metalworking foundry with chimney",
|
|
"mint_building": "mint building, coin production facility",
|
|
"tailoring_shop": "tailoring shop building, clothing workshop",
|
|
}
|
|
|
|
specific = prompts.get(building_name, clean_name)
|
|
|
|
return f"{specific}, game building asset, isometric view, {STYLE_PROMPT}"
|
|
|
|
|
|
def copy_latest_artifact(image_name: str, category: str) -> Path:
|
|
"""Find and copy latest generated artifact"""
|
|
|
|
# Find all matching artifacts
|
|
pattern = f"{image_name}_*.png"
|
|
artifacts = list(BRAIN_DIR.glob(pattern))
|
|
|
|
if not artifacts:
|
|
print(f" ❌ No artifact found for {image_name}")
|
|
return None
|
|
|
|
# Get latest
|
|
latest = max(artifacts, key=lambda p: p.stat().st_mtime)
|
|
|
|
# Create category dir
|
|
category_dir = ASSETS_DIR / category
|
|
category_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Copy
|
|
dest = category_dir / f"{image_name}.png"
|
|
shutil.copy2(latest, dest)
|
|
|
|
print(f" 📋 Copied to: {dest.relative_to(BASE_DIR)}")
|
|
return dest
|
|
|
|
|
|
def remove_background_rembg(image_path: Path):
|
|
"""Remove background using rembg"""
|
|
print(f" 🎨 Removing background...")
|
|
|
|
try:
|
|
from rembg import remove
|
|
from PIL import Image
|
|
|
|
with open(image_path, 'rb') as f:
|
|
input_data = f.read()
|
|
|
|
output_data = remove(input_data)
|
|
|
|
with open(image_path, 'wb') as f:
|
|
f.write(output_data)
|
|
|
|
print(f" ✅ Background removed!")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f" ⚠️ Background removal failed: {e}")
|
|
print(f" 💡 Install rembg: pip3 install rembg")
|
|
return False
|
|
|
|
|
|
def main():
|
|
"""Main generation loop"""
|
|
|
|
print("=" * 60)
|
|
print("🎨 INTEGRATED GRAVITY GENERATION PIPELINE")
|
|
print("=" * 60)
|
|
print(WORKFLOW_STEPS)
|
|
print("=" * 60)
|
|
|
|
print(f"\n📊 Buildings to generate: {len(BUILDINGS)}")
|
|
|
|
for i, building in enumerate(BUILDINGS, 1):
|
|
print(f"\n{'='*60}")
|
|
print(f"🏗️ [{i}/{len(BUILDINGS)}] {building}")
|
|
print(f"{'='*60}")
|
|
|
|
# Check if exists
|
|
dest_path = ASSETS_DIR / "buildings" / f"{building}.png"
|
|
if dest_path.exists():
|
|
print(f" ⏭️ SKIP: Already exists")
|
|
continue
|
|
|
|
# Generate prompt
|
|
prompt = generate_building_prompt(building)
|
|
print(f" 📝 Prompt: {prompt[:100]}...")
|
|
|
|
print(f"\n ⚠️ ACTION NEEDED:")
|
|
print(f" → Ask Antigravity to run:")
|
|
print(f" generate_image('{building}', '{prompt}')")
|
|
print(f"\n Then continue with:")
|
|
print(f" 1. Copy artifact to assets/images/buildings/")
|
|
print(f" 2. Run background removal")
|
|
|
|
# Placeholder - in real usage, Antigravity will generate here
|
|
break # Stop after showing workflow
|
|
|
|
print(f"\n{'='*60}")
|
|
print("📝 WORKFLOW INSTRUCTIONS COMPLETE")
|
|
print(f"{'='*60}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|