diff options
Diffstat (limited to 'prenderer.cpp')
-rw-r--r-- | prenderer.cpp | 176 |
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) |