File size: 13,269 Bytes
f4f1e64
238ec73
 
ada066c
 
 
 
 
 
 
 
 
 
 
 
f4f1e64
ada066c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f4f1e64
 
ada066c
 
 
 
 
 
 
 
 
 
 
 
5876552
ada066c
 
 
 
 
5876552
ada066c
1cb1db0
ada066c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5876552
ada066c
 
5876552
ada066c
1cb1db0
 
 
ada066c
 
 
1cb1db0
ada066c
5876552
ada066c
 
 
 
 
6668867
ada066c
 
 
 
1cb1db0
ada066c
5876552
ada066c
 
 
5876552
ada066c
 
 
 
 
 
5876552
ada066c
1cb1db0
 
5876552
ada066c
1cb1db0
ada066c
 
1cb1db0
ada066c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# core/prompt_engineering.py
import json

def create_cinematic_treatment_prompt(user_idea, genre, mood, num_scenes=3, creative_guidance="standard"):
    """
    Generates a prompt for Gemini to create a full cinematic treatment, including
    proactive suggestions for visual style, camera, sound, and even thematic elements.
    creative_guidance: "standard", "more_artistic", "experimental_narrative"
    """
    guidance_detail = {
        "standard": "Provide solid, genre-appropriate suggestions.",
        "more_artistic": "Lean into more artistic, unconventional, and visually striking suggestions for style and camera. Suggest unique color palettes or lighting.",
        "experimental_narrative": "Feel free to suggest a minor unexpected narrative twist or a symbolic visual motif that could enhance the story within one of the scenes."
    }[creative_guidance]

    return f"""
    You are an AI Creative Director and Master Storyteller, collaborating on a cinematic concept.
    Base Idea: "{user_idea}"
    Genre: "{genre}"
    Mood: "{mood}"
    Number of Key Scenes: {num_scenes}
    Creative Guidance Level: {creative_guidance} ({guidance_detail})

    Task: Develop a rich cinematic treatment. For EACH of the {num_scenes} key scenes, provide:
    1.  `scene_number` (int): Sequential.
    2.  `scene_title` (str): A short, evocative title for the scene (e.g., "The Neon Rains of Sector 7", "Echoes in the Void").
    3.  `setting_description` (str): Vivid, sensory details (sight, sound, atmosphere). Where are we? What makes it unique? (40-60 words).
    4.  `characters_involved` (list of str): Names of characters central to this scene.
    5.  `character_focus_moment` (str): For the primary character(s) in this scene, describe a key internal thought, subtle expression, or micro-action that reveals their state of mind or advances their arc.
    6.  `key_plot_beat` (str): The most critical plot development or character action in this scene (1-2 sentences).
    7.  `suggested_dialogue_hook` (str): One potent line of dialogue that captures the scene's essence or a character's voice. (If no dialogue, state "Silent scene").
    8.  `PROACTIVE_visual_style_감독` (str): Your proactive, detailed suggestion for this scene's visual style. Go beyond generic terms. Think specific art movements, film references, color theory, lighting techniques (e.g., "Dutch angles with chiaroscuro lighting, using a desaturated palette with piercing cyan highlights, reminiscent of early Tarkovsky but with a cyberpunk edge").
    9.  `PROACTIVE_camera_work_감독` (str): Your proactive suggestion for impactful camera work. Describe a specific shot or short sequence (e.g., "Slow dolly zoom into the protagonist's eyes, followed by a whip pan to reveal the approaching threat off-screen").
    10. `PROACTIVE_sound_design_감독` (str): Key ambient sounds, specific SFX, and a suggestion for the musical mood/instrumentation for this scene (e.g., "Ambient: Distant city hum, dripping water. SFX: Glitching electronic spark. Music: Low, ominous synth pads with a recurring, detuned piano motif").
    11. `dalle_image_prompt_keywords` (str): A concise list of 5-7 powerful keywords extracted from the above, specifically for generating a DALL-E image that captures the visual essence of this scene. Focus on nouns, strong adjectives, and artistic styles. (e.g., "cyberpunk alleyway, neon rain, lone figure, glowing data streams, high contrast, cinematic").
    12. `pexels_search_query_감독` (str): A concise, effective search query (2-4 words) for Pexels to find a background or atmospheric shot relevant to this scene's setting or mood (e.g., "rainy neon city," "vast desert landscape," "server room interior").

    If `creative_guidance` is "experimental_narrative", for one scene, you may subtly alter `key_plot_beat` or add a symbolic element to `setting_description` to introduce an unexpected twist, explaining your reasoning briefly in a `director_note` field for that scene only.

    Output ONLY a valid JSON list of these scene objects. Ensure all field names are exactly as specified (감독 denotes your proactive directorial input).
    """

# create_image_prompt_from_scene_data - THIS WILL NOW BE SIMPLER.
# Gemini already gave us dalle_image_prompt_keywords. We can build upon that.
def construct_dalle_prompt(scene_data, character_definitions=None, global_style_additions=""):
    """
    Constructs the final DALL-E prompt using keywords from Gemini,
    character details, and global style.
    """
    base_keywords = scene_data.get('dalle_image_prompt_keywords', 'cinematic scene')
    setting_desc = scene_data.get('setting_description', '') # For context
    action_desc = scene_data.get('key_plot_beat', '') # For context
    director_visual_style = scene_data.get('PROACTIVE_visual_style_감독', '')
    director_camera = scene_data.get('PROACTIVE_camera_work_감독', '')

    character_details_for_prompt = []
    # ... (Character injection logic remains the same as your last version, using char_name_lookup etc.)
    if scene_data.get('characters_involved'):
        for char_name_in_scene in scene_data.get('characters_involved', []):
            char_name_clean = char_name_in_scene.strip(); char_lookup_key = char_name_clean.lower()
            if character_definitions and char_lookup_key in character_definitions:
                character_details_for_prompt.append(f"{char_name_clean} ({character_definitions[char_lookup_key]})")
            else: character_prompt_segments.append(char_name_clean)
    
    character_narrative = ""
    if character_details_for_prompt:
        character_narrative = f" Characters featured: {', '.join(character_details_for_prompt)}."

    # DALL-E 3 often prefers more natural language but benefits from strong keywords.
    # We combine Gemini's suggestions with a structured approach.
    prompt = (
        f"Create an ultra-detailed, photorealistic, and highly cinematic masterpiece image. "
        f"Theme: '{scene_data.get('scene_title', 'A dramatic moment')}'. "
        f"Core visual elements based on keywords: {base_keywords}. " # Gemini's keywords
        f"{character_narrative} " # Injected character descriptions
        f"The scene unfolds in this setting: {setting_desc}. The key moment is: {action_desc}. "
        f"Artistic Direction -- Visual Style: {director_visual_style}. {global_style_additions}. "
        f"Cinematography -- Camera Work: {director_camera}. "
        f"Overall Impression: Evoke the mood of '{scene_data.get('mood', 'intense')}' with an atmosphere of '{scene_data.get('emotional_beat', 'suspense')}'. "
        f"Render with extreme detail, complex lighting, and rich textures suitable for a blockbuster film's concept art. "
    )
    return " ".join(prompt.split())


def create_narration_script_prompt_enhanced(story_scenes_data, overall_mood, overall_genre, voice_style="cinematic_trailer"):
    """
    Generates a more nuanced narration script prompt for Gemini.
    voice_style: "cinematic_trailer", "documentary_neutral", "introspective_character"
    """
    # ... (scene summary logic remains the same as your last version) ...
    scenes_summary = []
    for i, scene in enumerate(story_scenes_data):
        scenes_summary.append(
            f"Scene {scene.get('scene_number', i+1)} ({scene.get('scene_title','Untitled')} - {scene.get('emotional_beat','')})"
            f": {scene.get('key_plot_beat','')} Focus: {scene.get('character_focus_moment','')} "
            f"Soundscape hint: {scene.get('PROACTIVE_sound_design_감독','')}"
        )
    full_summary_text = "\n".join(scenes_summary)

    voice_style_description = {
        "cinematic_trailer": "deep, resonant, and slightly epic, building anticipation.",
        "documentary_neutral": "clear, informative, and objective.",
        "introspective_character": f"reflective, personal, perhaps echoing the thoughts of a key character (e.g., Jax, if present)."
    }[voice_style]

    prompt = f"""
    You are an award-winning voiceover scriptwriter.
    Craft a compelling, continuous narration script for a short cinematic animatic based on these scene insights:
    --- SCENE INSIGHTS ---
    {full_summary_text}
    --- END SCENE INSIGHTS ---

    Overall Genre: {overall_genre}
    Overall Mood: {overall_mood}
    Desired Voiceover Style: {voice_style} (Characteristics: {voice_style_description})

    The narration should:
    - Weave a cohesive narrative thread through the scenes.
    - Enhance emotional impact and atmosphere, guided by the scene's 'emotional_beat' and 'soundscape_hint'.
    - Be concise: Aim for 1-2 powerful sentences per scene. Total words ~60-100 for 3-4 scenes.
    - Avoid merely describing the action; instead, offer insight, build tension, or evoke thematic depth.
    - If style is 'introspective_character', imagine one of the characters is narrating their internal monologue.

    Output ONLY the pure narration script text, ready for text-to-speech. No scene numbers, no "VO:", just the spoken words.
    """
    return " ".join(prompt.split())

# create_scene_regeneration_prompt - Now uses the new fields
def create_scene_regeneration_prompt(original_scene_data, user_feedback, full_story_context=None):
    # ... (context_str same) ...
    context_str = f"Original scene (Scene Number {original_scene_data.get('scene_number')} - Title: {original_scene_data.get('scene_title')} ):\n{json.dumps(original_scene_data, indent=2)}\n\n"
    if full_story_context: context_str += f"Full story context:\n{json.dumps(full_story_context, indent=2)}\n\n"

    return f"""
    You are an AI Script Supervisor and Creative Consultant.
    {context_str}
    User Feedback for this scene: "{user_feedback}"

    Regenerate ONLY the JSON object for this single scene, incorporating the feedback.
    Maintain the exact field structure: (scene_number, scene_title, setting_description, characters_involved, character_focus_moment, key_plot_beat, suggested_dialogue_hook, PROACTIVE_visual_style_감독, PROACTIVE_camera_work_감독, PROACTIVE_sound_design_감독, dalle_image_prompt_keywords, pexels_search_query_감독).
    'scene_number' MUST NOT change.
    If feedback targets plot, characters, or dialogue, adjust relevant fields.
    If feedback targets visuals, camera, or sound, update the 'PROACTIVE_..._감독' fields AND the 'dalle_image_prompt_keywords' and 'pexels_search_query_감독' to reflect the new direction.
    Ensure 'key_plot_beat' is a concise sentence (max 15-20 words).
    If adding a `director_note` due to experimental narrative changes, ensure it's brief.
    """

# create_visual_regeneration_prompt - Now uses more context for Gemini to rewrite DALL-E prompt
def create_visual_regeneration_prompt(original_dalle_prompt, user_feedback, scene_data, character_definitions=None, global_style_additions=""):
    # ... (character_narrative same as in construct_dalle_prompt) ...
    characters_involved_in_scene = scene_data.get('characters_involved', [])
    character_prompt_segments = []
    if characters_involved_in_scene:
        for char_name_from_scene in characters_involved_in_scene:
            char_name_clean = char_name_from_scene.strip(); char_lookup_key = char_name_clean.lower()
            if character_definitions and char_lookup_key in character_definitions: character_prompt_segments.append(f"{char_name_clean} ({character_definitions[char_lookup_key]})")
            else: character_prompt_segments.append(char_name_clean)
    characters_narrative = f" Characters to feature: {', '.join(character_prompt_segments) if character_prompt_segments else 'None specifically detailed'}."

    full_prompt_for_gemini = f"""
    You are an AI Art Director specializing in refining DALL-E 3 prompts for cinematic visuals.
    The goal is to update an image prompt based on user feedback.

    Scene Context:
    - Title: "{scene_data.get('scene_title', '')}"
    - Setting: "{scene_data.get('setting_description', '')}"
    - Key Plot Beat: "{scene_data.get('key_plot_beat', '')}"
    - {characters_narrative}
    - Director's Suggested Visual Style: "{scene_data.get('PROACTIVE_visual_style_감독', '')}"
    - Director's Suggested Camera: "{scene_data.get('PROACTIVE_camera_work_감독', '')}"
    - Current Global Style Additions: "{global_style_additions}"

    The PREVIOUS DALL-E 3 prompt was:
    "{original_dalle_prompt}"

    User Feedback on the image generated by the previous prompt:
    "{user_feedback}"

    Your Task: Generate a NEW, revised DALL-E 3 prompt.
    This new prompt must incorporate the user's feedback to achieve the desired visual changes.
    It should remain ultra-detailed, photorealistic, and highly cinematic.
    The prompt should guide DALL-E 3 to create a stunning image suitable for a film's concept art.
    Maintain core scene elements (setting, characters, plot beat) unless feedback explicitly requests changes.
    Translate feedback into concrete visual descriptions (lighting, color, composition, character appearance/pose, atmosphere).
    Reinforce character descriptions if they are relevant to the feedback.

    Output ONLY the new, revised DALL-E 3 prompt string. Do not add any other text.
    """
    return " ".join(full_prompt_for_gemini.split())