Skip to content

Commit

Permalink
Merge pull request #20 from Panakotta00/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Panakotta00 authored Apr 6, 2023
2 parents 16b9c1e + 61fdc7d commit 887abc6
Show file tree
Hide file tree
Showing 196 changed files with 33,433 additions and 407 deletions.
Binary file modified Content/Styles/Sequencer.uasset
Binary file not shown.
2 changes: 1 addition & 1 deletion FicsItCam.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"FileVersion": 3,
"Version": 0,
"VersionName": "0.3",
"SemVersion": "0.3.4",
"SemVersion": "0.3.5",
"AcceptsAnyRemoteVersion": true,
"FriendlyName": "FicsIt-Cam",
"Description": "This mod allows you to create beautiful camera animations in-game.",
Expand Down
79 changes: 16 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,28 @@
# FicsItCam [![Build Status](https://jenkins.massivebytes.net/job/FicsIt-Cam/job/master/badge/icon)](https://jenkins.massivebytes.net/job/FicsIt-Cam/job/master/)

This Satisfactory mod is mainly intended for Content Creators to allow the creation of beautiful camera animations.
This Satisfactory mod is mainly intended for Content Creators to allow the creation of beautiful camera animations, timelapse recordings and other camera related things.

The mod introduces a couple of new chat commands:
- `/fic list`
Lists all animations.
- `/fic create <animation>`
Creates a new animation with the given name.
- `/fic delete <animation>`
Deletes the animation with the given name.
- `/fic play <animation>`
Plays the animation with the given name.
- `/fic edit <animation>`
Opens the animation editor for the animation with the given name.
- `/fic render <animation>`
Renders the animation as image sequence.
- `/fic timelapse list`
Lists all timelapse cameras.
- `/fic timelapse create <camera name> <seconds per frame>`
Creates a new timelapse camera with the transformation of the player running the command.
- `/fic timelapse delete <camera name>`
Removes the timelapse camera with the given name.
- `/fic timelapse start <camera name>`
Starts the timelapse camera with the given name.
- `/fic timelapse stop <camera name>`
Stops the timelapse camera with the given name.
Visit [SMR (aka. ficsit.app)](https://ficsit.app/mod/FicsItCam) for more information.

# Third-Party
This mod uses a third party library called [FFmpeg](https://ffmpeg.org) for converting images taken with FicsIt-Cam to MP4 files.

# Guide/Tutorial
Currently the best way to get to know all the features of FicsIt-Cam is [this in-depth Guide](https://www.youtube.com/watch?v=6Gl5rOFyqmM).

## Quick Help
Animation Rendering:
Animations can be render into a image sequence. Such Sequence is stored at `%localappdata%\FactoryGame\Saved\SaveGames\FicsItCam\<Animation Name>`.
The images have the resolution set in the animation.
Animations can be render into a mp4 (without audio). These mp4 files are located at `%localappdata%\FactoryGame\Saved\SaveGames\FicsItCam\<Scene Name>`.
The video should have the resolution set in the scene and as name the timestamp at start of the recording.

Timelapse Cameras:
Timelapse cameras can be used to take images of you factory in prediodic intervals and store these images in your filesystem.
Your gameplay wont bit disrupted, tho depending on your hardware you might experience a small lag

Animation Editor:
- The animation editor allows for creating and editing animation.
- On the bottom you can find the Timeline scrubber and range selector which allow you to view and change the currently active frame in the animation.
- Also on the bottom you find the graph viewer which shows the select attributes on the left in a time-value-diagram and also allows you to manipulate the keyframes.
- In the lower-left corner you find the frame settings were you can change the the active frame, change the animation range (length) and the selected frame range.
- On the left side you can find the details panel were you can view and change the current values of the properties (like location, rotation and FOV)
- Every property has a keyframe control which allows to set the keyframe at the active frame to the current value when clicking on the control and there is no keyframe or the keyframe differs from the current value.
- If at the current frame is a keyframe and the keyframe-value doesn't differ from the current value (has not changed) then a click removes the keyframe.
- If there is no keyframe is set at the active frame, the control is grey (nowere in the animation is a keyframe for that property) or dark orange (somewere else in the animation is a keyframe for that property).
- If there is a keyframe at the active frame, the control is orange (when the keyframe has not changed) or purple/blue (when the keyframe has changed)
- A double click on the keyframe control results in deletion of all keyframes of that property
- When clicking on the viewport you change into movement mode.
- When the active frame changes, all properties get updated to the value in the animation at that time. If no keyframe is set, is just stores that value.
- R-Clicking on a keyframe control allows to changed the interpolation type of the keyframe.
Your gameplay wont bit disrupted, tho depending on your hardware you might experience a small lag when the image gets taken.
Images are named with the timestamp of start of the timelapse (per game save session) and a incrementing number and are located under `%localappdata%\FactoryGame\Saved\SaveGames\FicsItCam\<Timelapse Camera Name>`.
Most Video Editing software does recognize the image sequences automatically on import, but sometimes you may need to use a tool like FFmpeg to convert them to a video with your specefied settings like framerate.

You can also use following key inputs:
- `Right Alt` -
Allows to switch between movement mode and cursor mode.
- `W`, `A`, `S`, `D`, `Space`, `Left Alt` and `Mouse Movement` -
Allows to move the camera around while beeing in movement mode
When holding shift you can also move faster around
- `Ctrl` + `Mouse-Wheel` -
Moves the active frame around
- `Shift` + `Mouse-Wheel` -
Changes the camera movement speed
- `N` -
Jump to the previous keyframe
- `M` -
Jump to the next keyframe
- `Arrow Left` -
Moves the active frame to the left
- `Arrow Right` -
Moves the active frame to the right
- `I` -
Sets the keyframes of all properties at the active frame to the current values.
If all properties have at the active frame unchanged keyframes, removes all keyframes at the current frame.
## Written Documentation
You can find a written documentation of the modification on [SMR aka. ficsit.app](https://ficsit.app/mod/FicsItCam).

## Contributors
- Panakotta00 (Development)
Expand Down
24 changes: 24 additions & 0 deletions Source/FicsItCam/FicsItCam.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,29 @@ public FicsItCam(ReadOnlyTargetRules Target) : base(Target)
PublicDependencyModuleNames.AddRange(new string[] {"FactoryGame", "SML"});

OptimizeCode = CodeOptimization.Never;

PublicIncludePaths.Add("Public");

var thirdPartyFolder = Path.Combine(ModuleDirectory, "../../ThirdParty");
PublicIncludePaths.Add(Path.Combine(thirdPartyFolder, "include"));

var platformName = Target.Platform.ToString();
var libraryFolder = Path.Combine(thirdPartyFolder, platformName);

PublicDelayLoadDLLs.Add("avcodec-60.dll");
PublicDelayLoadDLLs.Add("avformat-60.dll");
PublicDelayLoadDLLs.Add("swscale-7.dll");
PublicDelayLoadDLLs.Add("swresample-4.dll");
PublicDelayLoadDLLs.Add("avutil-58.dll");
RuntimeDependencies.Add("$(BinaryOutputDir)\\avcodec-60.dll", Path.Combine(libraryFolder, "avcodec-60.dll"));
RuntimeDependencies.Add("$(BinaryOutputDir)\\avformat-60.dll", Path.Combine(libraryFolder, "avformat-60.dll"));
RuntimeDependencies.Add("$(BinaryOutputDir)\\swscale-7.dll", Path.Combine(libraryFolder, "swscale-7.dll"));
RuntimeDependencies.Add("$(BinaryOutputDir)\\swresample-4.dll", Path.Combine(libraryFolder, "swresample-4.dll"));
RuntimeDependencies.Add("$(BinaryOutputDir)\\avutil-58.dll", Path.Combine(libraryFolder, "avutil-58.dll"));
PublicAdditionalLibraries.Add(Path.Combine(libraryFolder, "avcodec.lib"));
PublicAdditionalLibraries.Add(Path.Combine(libraryFolder, "avformat.lib"));
PublicAdditionalLibraries.Add(Path.Combine(libraryFolder, "swscale.lib"));
PublicAdditionalLibraries.Add(Path.Combine(libraryFolder, "swresample.lib"));
PublicAdditionalLibraries.Add(Path.Combine(libraryFolder, "avutil.lib"));
}
}
4 changes: 4 additions & 0 deletions Source/FicsItCam/Private/Data/Attributes/FICAttributeBool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ FICValue FFICAttributeBool::GetFloatValue(FICFrameFloat Time) {
return GetValue(Time) ? 1.0f : 0.0f;
}

bool FFICAttributeBool::HasKeyframe(FICFrame Time) const {
return Keyframes.Contains(Time);
}

void FFICAttributeBool::Set(TSharedRef<FFICAttribute> InAttrib) {
FOnUpdate OnUpdateBuf = OnUpdate;
if (InAttrib->GetAttributeType() == GetAttributeType()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ FICValue FFICFloatAttribute::GetFloatValue(FICFrameFloat Time) {
return GetValue(Time);
}

bool FFICFloatAttribute::HasKeyframe(FICFrame Time) const {
return Keyframes.Contains(Time);
}

void FFICFloatAttribute::Set(TSharedRef<FFICAttribute> InAttrib) {
FOnUpdate OnUpdateBuf = OnUpdate;
if (InAttrib->GetAttributeType() == GetAttributeType()) {
Expand Down
14 changes: 13 additions & 1 deletion Source/FicsItCam/Private/Data/Attributes/FICAttributeGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ TMap<FICFrame, TSharedRef<FFICKeyframe>> FFICGroupAttribute::GetKeyframes() {

void FFICKeyframeGroup::SetType(EFICKeyframeType Type) {
for (TPair<FString, FFICAttribute*> Child : Attribute->Children) {
TSharedRef<FFICKeyframe>* KF = Child.Value->GetKeyframes().Find(Frame);
TMap<FICFrame, TSharedRef<FFICKeyframe>> Keyframes = Child.Value->GetKeyframes();
TSharedRef<FFICKeyframe>* KF = Keyframes.Find(Frame);
if (KF) {
(*KF)->SetType(Type);
}
Expand Down Expand Up @@ -56,6 +57,13 @@ void FFICGroupAttribute::RecalculateKeyframe(FICFrame Time) {
}
}

bool FFICGroupAttribute::HasKeyframe(FICFrame Time) const {
for (TTuple<FString, FFICAttribute*> Child : Children) {
if (Child.Value->HasKeyframe(Time)) return true;
}
return false;
}

void FFICGroupAttribute::Set(TSharedRef<FFICAttribute> InAttrib) {
TSharedRef<FFICGroupAttribute> Attrib = StaticCastSharedRef<FFICGroupAttribute>(InAttrib);
for (const TPair<FString, FFICAttribute*>& Attr : Children) {
Expand All @@ -76,6 +84,10 @@ TSharedRef<FFICEditorAttributeBase> FFICGroupAttribute::CreateEditorAttribute()
return MakeShared<FFICEditorAttributeGroup>(*this);
}

const TMap<FString, FFICAttribute*>& FFICGroupAttribute::GetChildAttributes() const {
return Children;
}

void FFICGroupAttribute::AddChildAttribute(FString Name, FFICAttribute* Attribute) {
Children.Add(Name, Attribute);
UpdateDelegateHandles.Add(Name, Attribute->OnUpdate.AddLambda([this]() {
Expand Down
9 changes: 5 additions & 4 deletions Source/FicsItCam/Private/Editor/Data/FICEditorCameraActor.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Editor/Data/FICEditorCameraActor.h"

#include "FicsItCamModule.h"
#include "BaseGizmos/TransformGizmo.h"
#include "Components/LineBatchComponent.h"
#include "Components/SceneCaptureComponent2D.h"
Expand Down Expand Up @@ -72,10 +73,10 @@ uint32 FFICEditorCameraPathSceneProxy::GetMemoryFootprint() const {
}*/

void UFICEditorCameraPathComponent::UpdateFramePoints() {
FramePoints.SetNumUninitialized(EditorContext->GetScene()->AnimationRange.Length());
FramePoints.SetNumUninitialized(EditorContext->GetActiveRange().Length());
FramePoints.SetNumUninitialized(0, false);
KeyframePoints.Empty();
for (int64 Time : EditorContext->GetScene()->AnimationRange) {
for (int64 Time : EditorContext->GetActiveRange()) {
bool bIsKeyframe = EditorContext->GetEditorAttributes()[Camera]->Get<FFICEditorAttributeBase>("Position").GetKeyframe(Time).IsValid();
FVector Loc = FFICAttributePosition::FromEditorAttribute(EditorContext->GetEditorAttributes()[Camera]->Get<FFICEditorAttributeGroup>("Position"), Time);
if (bIsKeyframe) KeyframePoints.Add(FramePoints.Num());
Expand Down Expand Up @@ -135,6 +136,8 @@ void AFICEditorCameraActor::Tick(float DeltaSeconds) {
LineBatcher->DrawBox(FBox(FVector(-1, -1, -1), FVector(1, 1, 1)), Transform.GetScaled(FVector(60, 40, 40)).ToMatrixWithScale(), Color, SDPG_World);
LineBatcher->DrawDirectionalArrow((FTransform(FVector(60, 0, 0)) * GetActorTransform()).ToMatrixNoScale(), Color, 100, 20, SDPG_World);
LineBatcher->DrawLine(GetActorTransform().TransformPositionNoScale(FVector(0, 0, 40)), GetActorTransform().TransformPositionNoScale(FVector(0, 0, 100)), Color, SDPG_World);

CameraPathComponent->UpdateFramePoints();
}

CaptureComponent->HiddenActors.Empty();
Expand All @@ -149,8 +152,6 @@ void AFICEditorCameraActor::Tick(float DeltaSeconds) {
CameraPreview.Reset();
CaptureComponent->bCaptureEveryFrame = false;
}

CameraPathComponent->UpdateFramePoints();
}

UObject* AFICEditorCameraActor::Select() {
Expand Down
3 changes: 2 additions & 1 deletion Source/FicsItCam/Private/Editor/FICEditorContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void UFICEditorContext::Load(AFICEditorCameraCharacter* InEditorPlayerCharacter,
});

if (Scene->bViewportEverSaved) {
SetSelectedSceneObject(Scene->LastSelectedSceneObject);
if (Scene->GetSceneObjects().Contains(Scene->LastSelectedSceneObject)) SetSelectedSceneObject(Scene->LastSelectedSceneObject);
InEditorPlayerCharacter->SetActorLocation(Scene->LastCameraTransform.GetLocation());
InEditorPlayerCharacter->SetActorRotation(Scene->LastCameraTransform.GetRotation().Rotator());
}
Expand Down Expand Up @@ -229,6 +229,7 @@ FFICFrameRange UFICEditorContext::GetActiveRange() {
void UFICEditorContext::SetSelectedSceneObject(UObject* SceneObject) {
if (SelectedSceneObject) Cast<IFICSceneObject>(SelectedSceneObject)->Unselect(this);
SelectedSceneObject = SceneObject;
Scene->LastSelectedSceneObject = SceneObject;
if (SelectedSceneObject) Cast<IFICSceneObject>(SelectedSceneObject)->Select(this);
OnSceneObjectSelectionChanged.Broadcast();
}
Expand Down
Loading

0 comments on commit 887abc6

Please sign in to comment.