summaryrefslogtreecommitdiff
path: root/prenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'prenderer.cpp')
-rw-r--r--prenderer.cpp176
1 files changed, 153 insertions, 23 deletions
diff --git a/prenderer.cpp b/prenderer.cpp
index b61290a..dcb4577 100644
--- a/prenderer.cpp
+++ b/prenderer.cpp
@@ -1,3 +1,152 @@
+static v2
+T_CompUVToLayerUV(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, v2 CompUV)
+{
+ real32 X = CompUV.x*FileWidth;
+ real32 Y = CompUV.y*FileHeight;
+
+ real32 Rad = (T.rotation* (PI / 180));
+ v2 XAxis = (SourceWidth * T.scale)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (SourceHeight * -T.scale)*V2(sin(Rad), -cos(Rad));
+
+ v2 Pos = {T.x, T.y};
+ v2 Origin = Pos - (XAxis * T.ax) - (YAxis * T.ay);
+
+ v2 XAxisPerp = (1.0f / LengthSq(XAxis))*XAxis;
+ v2 YAxisPerp = (1.0f / LengthSq(YAxis))*YAxis;
+
+ real32 StartVectorX = X - Origin.x;
+ real32 StartVectorY = Y - Origin.y;
+ real32 LayerU = (StartVectorX * XAxisPerp.x) + (StartVectorY * XAxisPerp.y);
+ real32 LayerV = (StartVectorX * YAxisPerp.x) + (StartVectorY * YAxisPerp.y);
+ return V2(LayerU, LayerV);
+}
+
+static v2
+T_CompPosToLayerPos(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, v2 CompUV)
+{
+ v2 UV = T_CompUVToLayerUV(T, FileWidth, FileHeight, SourceWidth, SourceHeight, CompUV/V2(FileWidth, FileHeight));
+ return UV*V2(SourceWidth, SourceHeight);
+}
+
+static v2
+Transform_ScreenSpaceToLocal(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight,
+ ui UI, ImVec2 ViewportMin, ImVec2 Point)
+{
+ v2 CompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI.CompPos, UI.CompZoom, Point);
+ v2 LayerUV = T_CompUVToLayerUV(T, FileWidth, FileHeight, SourceWidth, SourceHeight, CompUV);
+ return V2(LayerUV.x * SourceWidth, LayerUV.y * SourceHeight);
+}
+
+// Transform given data based on state's Interact data.
+static void
+Transform_ApplyInteractive(interact_transform Interact, real32 *OutputX, real32 *OutputY, real32 *OutputRotation, real32 *OutputScale)
+{
+ v2 BoxLength = Interact.Max - Interact.Min;
+ v2 Center = Interact.Max - (BoxLength/2);
+
+ real32 Point0X = Center.x - *OutputX;
+ real32 Point0Y = Center.y - *OutputY;
+
+ real32 Rad = Interact.Radians;
+ real32 Rotation = Interact.Radians / (PI / 180);
+
+ v2 XAxis = (Point0X * Interact.Scale)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Point0Y * -Interact.Scale)*V2(sin(Rad), -cos(Rad));
+
+ real32 X0 = -XAxis.x - YAxis.x + Center.x;
+ real32 Y0 = -XAxis.y - YAxis.y + Center.y;
+
+ *OutputX = X0 + Interact.Position.x;
+ *OutputY = Y0 + Interact.Position.y;
+ *OutputRotation += Rotation;
+ *OutputScale += Interact.Scale - 1.0f;
+}
+
+static void
+Transform_IterateOuterBounds(block_layer *Layer, block_source *Source, real32 *MinX, real32 *MinY, real32 *MaxX, real32 *MaxY)
+{
+ real32 Rad = (Layer->rotation.CurrentValue * (PI / 180));
+ real32 s = Layer->scale.CurrentValue;
+
+ v2 XAxis = (Source->Width * s)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Source->Height * -s)*V2(sin(Rad), -cos(Rad));
+
+ real32 AnchorX = Layer->ax.CurrentValue;
+ real32 AnchorY = Layer->ay.CurrentValue;
+
+ v2 Pos = {Layer->x.CurrentValue, Layer->y.CurrentValue};
+ v2 Origin = Pos - (XAxis * AnchorX) - (YAxis * AnchorY);
+
+ real32 XLengthSq = 1.0f / LengthSq(XAxis);
+ real32 YLengthSq = 1.0f / LengthSq(YAxis);
+
+ v2 Points[4] = {Origin, Origin + XAxis, Origin + YAxis, Origin + XAxis + YAxis};
+ for (int i = 0; i < 4; i++) {
+ if (Points[i].x < *MinX) { *MinX = Points[i].x; }
+ if (Points[i].y < *MinY) { *MinY = Points[i].y; }
+ if (Points[i].x > *MaxX) { *MaxX = Points[i].x; }
+ if (Points[i].y > *MaxY) { *MaxY = Points[i].y; }
+ }
+}
+
+// IMPORTANT(fox): The selection state and ordering of layers cannot change
+// until this action is exited/committed!
+static void
+Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos)
+{
+ real32 MinX = 100000;
+ real32 MinY = 100000;
+ real32 MaxX = -100000;
+ real32 MaxY = -100000;
+ bool32 Activate = false;
+ // Find the max dimensions of all the selected layers.
+ for (int i = 0; i < File->Layer_Count; i++) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (!Layer->IsSelected)
+ continue;
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Transform_IterateOuterBounds(Layer, Source, &MinX, &MinY, &MaxX, &MaxY);
+ Activate = true;
+ }
+ if (Activate) {
+ State->Interact_Active = interact_type_viewport_transform;
+ interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0];
+ Interact->Min = V2(MinX, MinY);
+ Interact->Max = V2(MaxX, MaxY);
+ Interact->Position = V2(0);
+ Interact->Radians = 0;
+ Interact->Scale = 1.0f;
+ Interact->OGPos = OGPos;
+ }
+}
+
+static ImVec2
+Layer_LocalToScreenSpace(project_state *State, block_layer *Layer, ui *UI,
+ real32 SourceWidth, real32 SourceHeight, real32 CompWidth, real32 CompHeight, v2 Point)
+{
+ real32 Rotation = Layer->rotation.CurrentValue;
+ real32 s = Layer->scale.CurrentValue;
+ real32 X = Layer->x.CurrentValue;
+ real32 Y = Layer->y.CurrentValue;
+
+ if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected) {
+ Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &X, &Y, &Rotation, &s);
+ }
+
+ real32 Rad = (Rotation * (PI / 180));
+ real32 AX = Layer->ax.CurrentValue;
+ real32 AY = Layer->ay.CurrentValue;
+
+ v2 XAxis = (Point.x - AX*SourceWidth) * s * V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Point.y - AY*SourceHeight) * -s * V2(sin(Rad), -cos(Rad));
+ v2 LocalPoint = XAxis + YAxis;
+ v2 CompUV = V2((X + LocalPoint.x) / CompWidth,
+ (Y + LocalPoint.y) / CompHeight);
+ v2 ScreenPoint = V2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
+ UI->CompPos.y + CompUV.y * UI->CompZoom.y);
+
+ return ImVec2(ScreenPoint.x, ScreenPoint.y);
+}
static void
Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegion);
@@ -31,29 +180,6 @@ Renderer_Check(bool32 *Test)
*Test = Threading_IsActive();
}
-// Helper for working with different bit depths.
-static render_byte_info
-Bitmap_ByteInfo(uint32 BytesPerPixel) {
- render_byte_info Byte = {};
- if (BytesPerPixel == 4) {
- Byte.MaskPixel = 0xFF;
- Byte.ByteOffset = 1;
- Byte.Normalized = 1 / 255.0f;
- Byte.Bits = 255;
- } else if (BytesPerPixel == 8) {
- Byte.MaskPixel = 0xFFFF;
- Byte.ByteOffset = 2;
- Byte.Normalized = 1 / 65535.0f;
- Byte.Bits = 65535;
- } else {
- Byte.MaskPixel = 0xFFFFFFFF;
- Byte.ByteOffset = 4;
- Byte.Normalized = 1 / 4294967295.0f;
- Byte.Bits = 4294967295;
- Assert(0);
- }
- return Byte;
-}
static transform_info
Transform_Calculate(project_state *State, memory *Memory, project_data *File, block_layer *Layer, block_composition *Comp)
@@ -78,6 +204,10 @@ Transform_Calculate(project_state *State, memory *Memory, project_data *File, bl
real32 s = Layer->scale.CurrentValue;
blend_mode BlendMode = Layer->BlendMode;
+ if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected) {
+ Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &X, &Y, &Rotation, &s);
+ }
+
/*
state_file_ui *UI = &State->Context[State->CurrentFileIndex].UI;
if (UI->IsInteracting == true && UI->InteractMode == interact_transforms && Layer->IsSelected && !Layer->IsAdjustment)