diff --git a/dependencies/blenderScript.py b/dependencies/blenderScript.py index 2578efd..64a39d4 100644 --- a/dependencies/blenderScript.py +++ b/dependencies/blenderScript.py @@ -55,14 +55,15 @@ while True: else: StickMode = 1 - fps = int(settingsRoot[0].text) width = int(settingsRoot[1].text) StickDistance = _map(int(settingsRoot[2].text), 0, 100, 5, 105) if(command == "startRendering"): - logs = settingsRoot[4].text[1:][:-1].split("\"\"") - output = settingsRoot[5].text + fps = int(settingsRoot[0].text) + videoFormat = settingsRoot[4].text + logs = settingsRoot[5].text[1:][:-1].split("\"\"") + output = settingsRoot[6].text logCount = len(logs) logNumber = 1 @@ -105,8 +106,27 @@ while True: logger.error("Can't read Log: " + (Str)(e)) bpy.context.scene.render.image_settings.file_format = 'FFMPEG' - bpy.context.scene.render.ffmpeg.format = "QUICKTIME" - bpy.context.scene.render.ffmpeg.codec = "QTRLE" + + if(videoFormat == "mp4"): + bpy.context.scene.render.ffmpeg.format = 'MPEG4' + bpy.context.scene.render.ffmpeg.codec = 'H264' + bpy.context.scene.render.image_settings.color_mode = 'RGB' + elif(videoFormat == "mov"): + bpy.context.scene.render.ffmpeg.format = 'QUICKTIME' + bpy.context.scene.render.ffmpeg.codec = 'QTRLE' + bpy.context.scene.render.image_settings.color_mode = 'RGBA' + elif(videoFormat == "avi"): + bpy.context.scene.render.ffmpeg.format = 'AVI' + bpy.context.scene.render.ffmpeg.codec = 'FFV1' + bpy.context.scene.render.image_settings.color_mode = 'RGBA' + elif(videoFormat == "webm"): + bpy.context.scene.render.ffmpeg.format = 'WEBM' + bpy.context.scene.render.ffmpeg.codec = 'WEBM' + bpy.context.scene.render.image_settings.color_mode = 'RGBA' + elif(videoFormat == "mkv"): + bpy.context.scene.render.ffmpeg.format = 'MKV' + bpy.context.scene.render.ffmpeg.codec = 'WEBM' + bpy.context.scene.render.image_settings.color_mode = 'RGBA' scn.render.resolution_x = width GimbalCoverR.location[0] = StickDistance @@ -116,7 +136,7 @@ while True: Camera.location[0] = StickDistance/2 Camera.data.ortho_scale = StickDistance+5 scn.render.resolution_y = int(width/_map(StickDistance, 5, 105, 2, 21.6)) - bpy.context.scene.render.filepath = output + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", ".mov") + bpy.context.scene.render.filepath = output + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", "."+videoFormat) scn.render.fps = 1000 scn.render.fps_base = FPSxxx @@ -143,32 +163,26 @@ while True: bpy.context.scene.frame_set(frame) + StickL.rotation_euler=[0,0,0] + GimbalL.rotation_euler=[0,0,0] + StickR.rotation_euler=[0,0,0] + GimbalR.rotation_euler=[0,0,0] + if StickMode == "1": - StickL.rotation_euler=[0,0,0] StickL.rotation_euler.rotate_axis("Y", ailP) - StickL.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalL.rotation_euler=[0,0,0] GimbalL.rotation_euler.rotate_axis("X", eleP) - GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) - StickR.rotation_euler=[0,0,0] StickR.rotation_euler.rotate_axis("Y", rudP) - StickR.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalR.rotation_euler=[0,0,0] GimbalR.rotation_euler.rotate_axis("X", thrP) - GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) else: - StickL.rotation_euler=[0,0,0] StickL.rotation_euler.rotate_axis("Y", rudP) - StickL.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalL.rotation_euler=[0,0,0] GimbalL.rotation_euler.rotate_axis("X", thrP) - GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) - StickR.rotation_euler=[0,0,0] StickR.rotation_euler.rotate_axis("Y", ailP) - StickR.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalR.rotation_euler=[0,0,0] GimbalR.rotation_euler.rotate_axis("X", eleP) - GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) + + StickL.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) + StickR.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) logger.info("Init:" + ((str)(frame)) + ":") frame+=1 @@ -183,7 +197,6 @@ while True: elif(command == "getRender"): bpy.context.scene.render.image_settings.file_format = 'PNG' - bpy.context.scene.frame_set(0) bpy.context.scene.render.filepath = argv[0] + "\\render.png" scn.render.resolution_x = width @@ -195,17 +208,52 @@ while True: Camera.data.ortho_scale = StickDistance+5 scn.render.resolution_y = int(width/_map(StickDistance, 5, 105, 2, 21.6)) + bpy.context.scene.frame_set(0) + StickL.rotation_euler=[0,0,0] - StickL.rotation_euler.rotate_axis("Y", 0.436) - StickL.keyframe_insert(data_path="rotation_euler", index=-1) GimbalL.rotation_euler=[0,0,0] - GimbalL.rotation_euler.rotate_axis("X", 0.236) - GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) StickR.rotation_euler=[0,0,0] - StickR.rotation_euler.rotate_axis("Y", -0.056) - StickR.keyframe_insert(data_path="rotation_euler", index=-1) GimbalR.rotation_euler=[0,0,0] - GimbalR.rotation_euler.rotate_axis("X", -0.436) + + if(StickMode == 2): + StickL.rotation_euler.rotate_axis("Y", 0) + GimbalL.rotation_euler.rotate_axis("X", 0.436) + StickR.rotation_euler.rotate_axis("Y", 0) + GimbalR.rotation_euler.rotate_axis("X", 0) + else: + StickL.rotation_euler.rotate_axis("Y", 0) + GimbalL.rotation_euler.rotate_axis("X", 0) + StickR.rotation_euler.rotate_axis("Y", 0) + GimbalR.rotation_euler.rotate_axis("X", 0.436) + + StickL.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) + StickR.keyframe_insert(data_path="rotation_euler", index=-1) GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) + bpy.context.scene.frame_set(1) + + StickL.rotation_euler=[0,0,0] + GimbalL.rotation_euler=[0,0,0] + StickR.rotation_euler=[0,0,0] + GimbalR.rotation_euler=[0,0,0] + + if(StickMode == 2): + StickL.rotation_euler.rotate_axis("Y", 0) + GimbalL.rotation_euler.rotate_axis("X", 0.436) + StickR.rotation_euler.rotate_axis("Y", 0) + GimbalR.rotation_euler.rotate_axis("X", 0) + else: + StickL.rotation_euler.rotate_axis("Y", 0) + GimbalL.rotation_euler.rotate_axis("X", 0) + StickR.rotation_euler.rotate_axis("Y", 0) + GimbalR.rotation_euler.rotate_axis("X", 0.436) + + StickL.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) + StickR.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) + + bpy.context.scene.frame_set(0) + bpy.ops.render.render(write_still=True) \ No newline at end of file diff --git a/src/components/settings.ts b/src/components/settings.ts index 626af49..5d0db1d 100644 --- a/src/components/settings.ts +++ b/src/components/settings.ts @@ -7,11 +7,20 @@ function getXMLChild(doc:Document, child:string) { return String(doc.getElementsByTagName(child)[0].childNodes[0].nodeValue); } +enum VideoFormat { + mp4="mp4", + mov="mov", + webm="webm", + avi="avi", + mkv="mkv", +} + const defaultSettings = { fps: 30, width: 540, stickDistance: 5, stickMode2: true, + videoFormat: VideoFormat.webm, log: '', output: defaultOutputPath } @@ -29,6 +38,7 @@ const settingList = await fetch(SettingPath).then(function(response) { width: parseInt(getXMLChild(xmlDoc, "width")), stickDistance: parseInt(getXMLChild(xmlDoc, "stickDistance")), stickMode2: (getXMLChild(xmlDoc, "stickMode2") === "true"), + videoFormat: getXMLChild(xmlDoc, "videoFormat") as unknown as VideoFormat, log: (getXMLChild(xmlDoc, "log") === "None")? "":getXMLChild(xmlDoc, "log"), output: getXMLChild(xmlDoc, "output") } @@ -38,7 +48,7 @@ const settingList = await fetch(SettingPath).then(function(response) { }); if(!loadedSuccessfully) updateSettings({}); -function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:number, stickMode2?:boolean, log?:string, output?:string}) { +function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:number, stickMode2?:boolean, videoFormat?:VideoFormat, log?:string, output?:string}) { if(optiones.fps === undefined) { optiones.fps = settingList.fps; } else { @@ -59,6 +69,11 @@ function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:num } else { settingList.stickMode2 = optiones.stickMode2; } + if(optiones.videoFormat === undefined) { + optiones.videoFormat = settingList.videoFormat; + } else { + settingList.videoFormat = optiones.videoFormat; + } if(optiones.log === undefined) { optiones.log = settingList.log; } else { @@ -70,13 +85,18 @@ function updateSettings(optiones:{fps?:number, width?:number, stickDistance?:num settingList.output = optiones.output; } - const xmlStr = '' + optiones.fps + - '' + optiones.width + - '' + optiones.stickDistance + - '' + ((optiones.stickMode2)?"true":"false") + - '' + ((optiones.log === "")? "None":optiones.log) + - '' + optiones.output + - ''; + const xmlStr = ` + + + ${optiones.fps} + ${optiones.width} + ${optiones.stickDistance} + ${optiones.stickMode2} + ${optiones.videoFormat} + ${(optiones.log === "")?"None":optiones.log} + ${optiones.output} + + `; fs.writeFile(SettingPath, formatXML(xmlStr, {collapseContent: true}), function(err) { if(err) { @@ -90,7 +110,8 @@ function settingListLoadDefault() { fps:defaultSettings.fps, width:defaultSettings.width, stickDistance:defaultSettings.stickDistance, - stickMode2:defaultSettings.stickMode2 + stickMode2:defaultSettings.stickMode2, + videoFormat:defaultSettings.videoFormat, }); } @@ -109,5 +130,6 @@ export { settingListLoadDefault, settingList, getLogList, - getLogSize + getLogSize, + VideoFormat } \ No newline at end of file diff --git a/src/components/ui/settingsSide.tsx b/src/components/ui/settingsSide.tsx index 21f7296..dd0e68b 100644 --- a/src/components/ui/settingsSide.tsx +++ b/src/components/ui/settingsSide.tsx @@ -1,5 +1,5 @@ -import React, {useState, useEffect} from "react"; -import { settingList, updateSettings, settingListLoadDefault } from "../settings"; +import React, {useState, useEffect, CSSProperties} from "react"; +import { settingList, updateSettings, settingListLoadDefault, VideoFormat } from "../settings"; import {blender, blenderCmd, renderingPicture} from "../blenderController"; import {dataPath} from "../paths"; import path from "path"; @@ -21,12 +21,49 @@ const RenderLoadingSpinner = () => ( ); +function VideoFormatWarning({videoFormat}:{videoFormat:VideoFormat}) { + let message = ""; + + switch(videoFormat) { + case VideoFormat.mp4: + message = "mp4 has no support for alpha channel and the background will be black."; + break; + case VideoFormat.avi: + message = "avi can't be played in the preview of this app."; + break; + case VideoFormat.mkv: + message = "mkv can't be played in the preview of this app."; + break; + case VideoFormat.mov: + message = "mov can't be played in the preview of this app."; + break; + } + + const style:CSSProperties = { + height: "30px", + width: "30px", + fill: "orange", + paddingLeft: "5px", + + }; + + return ( +
+ + {/* */} + + +
+ ); +} + function SettingsSide() { const [fps, setFps] = useState(settingList.fps); const [width, setWidth] = useState(settingList.width); const [stickDistance, setStickDistance] = useState(settingList.stickDistance); const [stickMode2, setStickMode2] = useState(settingList.stickMode2); + const [videoFormat, setVideoFormat] = useState(settingList.videoFormat); const [renderImg, setRenderImgInner] = useState(picturePath()); setRenderImg = setRenderImgInner; const [renderLoading, setRenderLoadingInner] = useState(renderingPicture); @@ -34,15 +71,27 @@ function SettingsSide() { useEffect(() => { const timer = setTimeout(() => { - updateSettings({fps, width, stickDistance, stickMode2}); + updateSettings({width, stickDistance, stickMode2}); blender(blenderCmd.getRender); }, 500); return () => clearTimeout(timer); - }, [fps, width, stickDistance, stickMode2]); + }, [width, stickDistance, stickMode2]); + + useEffect(() => { + const timer = setTimeout(() => { + updateSettings({fps, videoFormat}); + }, 500); + + return () => clearTimeout(timer); + }, [fps, videoFormat]); sideLoaded = true; + const VideoFormatOptions = Object.keys(VideoFormat).filter((el) => { return isNaN(Number(el)) }).map(key => { + return ; + }); + return (
@@ -53,13 +102,13 @@ function SettingsSide() { }}/> - + { if(e.target.value.trim().length !== 0) setWidth(parseInt(e.target.value)); }}/> - + { if(e.target.value.trim().length !== 0) setStickDistance(parseInt(e.target.value)); }}/> @@ -67,7 +116,7 @@ function SettingsSide() {
-

Stick Mode:

+

Stick Mode

+ + + + {videoFormat === VideoFormat.mov? : null} + {videoFormat === VideoFormat.mp4? : null} + {videoFormat === VideoFormat.avi? : null} +
diff --git a/src/index.css b/src/index.css index 63aae9c..46dfad0 100644 --- a/src/index.css +++ b/src/index.css @@ -404,4 +404,28 @@ button:hover { justify-content: center; align-items: center; font-size: large; +} + +.selectSpan { + display: flex; + align-items: center; +} +.selectSpanSelect select { + padding: 8px 0; + border: 0; + border-top-right-radius: 18px; + border-bottom-right-radius: 18px; + cursor: pointer; + text-align: center; + font-size: large; +} +.selectSpanLabel { + padding: 10px 10px; + background: #00c24a; + border-top-left-radius: 18px; + border-bottom-left-radius: 18px; + font-weight: bolder; +} +#videoFormatWarning:hover { + transform: scale(1.05); } \ No newline at end of file