summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2023-01-06 23:11:49 -0500
committerFox Caminiti <fox@foxcam.net>2023-01-06 23:11:49 -0500
commit1d0d8549411e23394059f420f053cc3ee28dacfb (patch)
treec4486e5632c09d11acfae5634dceb3db6d6dba97
parent84d04d391bc4bf9481106d4f5ac4d3dd8f27ed87 (diff)
more shape code
-rw-r--r--src/bezier.cpp55
-rw-r--r--src/gl_calls.cpp136
-rw-r--r--src/imgui_ui_properties.cpp27
-rw-r--r--src/imgui_ui_viewport.cpp4
-rw-r--r--src/include/functions.h6
-rw-r--r--src/layer.cpp5
-rw-r--r--src/nanovg.cpp29
7 files changed, 163 insertions, 99 deletions
diff --git a/src/bezier.cpp b/src/bezier.cpp
index 1585495..b90e146 100644
--- a/src/bezier.cpp
+++ b/src/bezier.cpp
@@ -34,20 +34,53 @@ Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 Tar
return Y;
}
+// All the extra inputs on the second line are for when we need to take
+// interactive mode into account.
// TODO(fox): Incorporate sorting for non-continuous shapes.
static uint32
-Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData)
+Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData,
+ project_state *State, layer_transforms T, int Width, int Height,
+ int CompWidth, int CompHeight, bool32 Interact)
{
real32 Radius = Shape->Opt.Roundness;
bezier_point *PointStart = PointData;
for (int i = 0; i < Shape->Point_Count; i++) {
- bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
- if (Radius <= 0 && Point->Type == interpolation_type_linear) {
- v2 Pos = Point->Pos[0];
+ bezier_point Point = *Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+ if (State->Interact_Active == interact_type_keyframe_move && Interact && Point.IsSelected) {
+ v2 Pos = Point.Pos[0];
+ Pos = TransformPoint(T, Width, Height, Pos);
+ Pos.x += State->Interact_Offset[0];
+ Pos.y += State->Interact_Offset[1];
+ Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
+ Point.Pos[0] = Pos;
+ }
+ // Corner rounder
+ if ((Radius > 0 && Point.Type == interpolation_type_linear) &&
+ (Shape->IsClosed || (i != 0 && i != (Shape->Point_Count - 1)) )) {
+ v2 Pos = Point.Pos[0];
int Index_Prev = (i != 0) ? i-1 : Shape->Point_Count-1;
int Index_Next = (i != Shape->Point_Count-1) ? i+1 : 0;
- v2 Pos_Prev = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Prev, 1)->Pos[0];
- v2 Pos_Next = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Next, 1)->Pos[0];
+ bezier_point *Point_Prev = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Prev, 1);
+ bezier_point *Point_Next = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Next, 1);
+ v2 Pos_Prev = Point_Prev->Pos[0];
+ v2 Pos_Next = Point_Next->Pos[0];
+ // TODO(fox): debloat
+ if (State->Interact_Active == interact_type_keyframe_move && Interact && Point_Prev->IsSelected) {
+ v2 Pos = Pos_Prev;
+ Pos = TransformPoint(T, Width, Height, Pos);
+ Pos.x += State->Interact_Offset[0];
+ Pos.y += State->Interact_Offset[1];
+ Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
+ Pos_Prev = Pos;
+ }
+ if (State->Interact_Active == interact_type_keyframe_move && Interact && Point_Next->IsSelected) {
+ v2 Pos = Pos_Next;
+ Pos = TransformPoint(T, Width, Height, Pos);
+ Pos.x += State->Interact_Offset[0];
+ Pos.y += State->Interact_Offset[1];
+ Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
+ Pos_Next = Pos;
+ }
v2 Vector_Prev = Pos - Pos_Prev;
v2 Vector_Next = Pos - Pos_Next;
real32 Length_Prev = sqrtf(LengthSq(Vector_Prev));
@@ -56,10 +89,10 @@ Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData)
// real32 RadAngle = acos(Inner(Vector_Prev, VectorR) / (LengthL * LengthR)) * PI / 180;
// real32 AngleKappa = (4.f/3) * tan(RadAngle * 1/4);
- real32 Ratio_Prev = Radius / Length_Prev;
+ real32 Ratio_Prev = Min(Radius / Length_Prev, 0.5);
real32 Ratio_Prev_Inv = 1.0f - Ratio_Prev;
- real32 Ratio_Next = Radius / Length_Next;
+ real32 Ratio_Next = Min(Radius / Length_Next, 0.5);
real32 Ratio_Next_Inv = 1.0f - Ratio_Next;
v2 Point_1 = Pos_Prev + V2(Vector_Prev.x * Ratio_Prev_Inv, (Vector_Prev.y * Ratio_Prev_Inv));
@@ -67,10 +100,10 @@ Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData)
v2 Point_3 = Pos_Next + V2(Vector_Next.x * Ratio_Next_Inv, Vector_Next.y * Ratio_Next_Inv);
v2 Point_4 = Vector_Next * Ratio_Next * (1-KAPPA);
- *PointData++ = { 1, { Point_1, Point_2, V2(0, 0) }, interpolation_type_bezier, 0 };
- *PointData++ = { 1, { Point_3, V2(0, 0), Point_4 }, interpolation_type_bezier, 0 };
+ *PointData++ = { 1, { Point_1, Point_2, V2(0, 0) }, interpolation_type_bezier, Point.IsSelected };
+ *PointData++ = { 1, { Point_3, V2(0, 0), Point_4 }, interpolation_type_bezier, Point.IsSelected };
} else {
- *PointData++ = *Point;
+ *PointData++ = Point;
}
}
return PointData - PointStart;
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp
index a1938be..3db9e6a 100644
--- a/src/gl_calls.cpp
+++ b/src/gl_calls.cpp
@@ -206,53 +206,59 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeDa
Uniform = glGetUniformLocation(DefaultShaderProgram, "Scale");
glUniform1f(Uniform, T.scale);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
- glUniform1i(Uniform, 1);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
- glUniform1i(Uniform, 1);
-
- // fill
- // vertices
- glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * FillCount, FillData, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
-
- // stencil buffer
- glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
- glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
- glDisable(GL_CULL_FACE);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
- //
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glBindVertexArray(0);
+ if (RenderMode == 0 || RenderMode == 1)
+ {
- Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
- glUniform1i(Uniform, 0);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
- glUniform1i(Uniform, 1);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol");
- glUniform3f(Uniform, FillCol.r, FillCol.g, FillCol.b);
-
- // stencil for fill
- //
- // vertices
- glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
-
- // stencil buffer
- glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
- glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
-
- glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
- //
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(Uniform, 1);
+
+ // fill
+ // vertices
+ glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * FillCount, FillData, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
+
+ // stencil buffer
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
+ glDisable(GL_CULL_FACE);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
+ //
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glBindVertexArray(0);
+
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ glUniform1i(Uniform, 0);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol");
+ glUniform3f(Uniform, FillCol.r, FillCol.g, FillCol.b);
+
+ // stencil for fill
+ //
+ // vertices
+ glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+
+ // stencil buffer
+ glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
+ glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+
+ glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
+ //
+ } else {
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }
// stencil buffer not needed
glDisable(GL_STENCIL_TEST);
@@ -261,24 +267,26 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeDa
glBindVertexArray(0);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
- glUniform1i(Uniform, 1);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
- glUniform1i(Uniform, 1);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol");
- glUniform3f(Uniform, StrokeCol.r, StrokeCol.g, StrokeCol.b);
-
- // stroke
- //
- glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * StrokeCount, StrokeData, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
- glEnableVertexAttribArray(1);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, StrokeCount);
- //
+ if (RenderMode == 0 || RenderMode == 2) {
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol");
+ glUniform3f(Uniform, StrokeCol.r, StrokeCol.g, StrokeCol.b);
+
+ // stroke
+ //
+ glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * StrokeCount, StrokeData, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, StrokeCount);
+ //
+ }
glBindFramebuffer(GL_READ_FRAMEBUFFER, TestM->FramebufferObject);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, TestL->FramebufferObject);
diff --git a/src/imgui_ui_properties.cpp b/src/imgui_ui_properties.cpp
index 6f949c8..83adcf1 100644
--- a/src/imgui_ui_properties.cpp
+++ b/src/imgui_ui_properties.cpp
@@ -434,11 +434,13 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
if (Layer->IsShapeLayer) {
shape_options *Opt = &Layer->Shape.Opt;
// TODO(fox): Combine with RGBA function?
- char *Names[3] = { "Fill only", "Stroke only", "Fill and stroke" };
+ char *Names[3] = { "Fill and stroke", "Fill only", "Stroke only" };
if (ImGui::BeginListBox("Shape render type")) {
for (int i = 0; i < 3; i++) {
if (ImGui::Selectable(Names[i], (Opt->Visibility == i))) {
Opt->Visibility = i;
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
}
}
ImGui::EndListBox();
@@ -449,6 +451,8 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
for (int i = 0; i < 2; i++) {
if (ImGui::Selectable(Names2[i], (Opt->LineCapType == CapVals[i]))) {
Opt->LineCapType = CapVals[i];
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
}
}
ImGui::EndListBox();
@@ -460,15 +464,36 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
if (ImGui::Selectable(Names3[i], (Opt->LineJoinType == JoinVals[i]))) {
Opt->Visibility = i;
Opt->LineJoinType = JoinVals[i];
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
}
}
ImGui::EndListBox();
}
ImGui::ColorEdit4("Fill color", (real32 *)&Opt->FillCol, ImGuiColorEditFlags_Float);
+ if (ImGui::IsItemActive()) {
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
+ }
ImGui::ColorEdit4("Stroke color", (real32 *)&Opt->StrokeCol, ImGuiColorEditFlags_Float);
+ if (ImGui::IsItemActive()) {
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
+ }
real32 StrokeWidthMin = 0;
real32 StrokeWidthMax = 1024;
ImGui::DragScalar("Stroke width", ImGuiDataType_Float, &Opt->StrokeWidth, 1, &StrokeWidthMin, &StrokeWidthMax, "%.3f");
+ if (ImGui::IsItemActive()) {
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
+ }
+ real32 RoundnessMin = 0;
+ real32 RoundnessMax = 1024;
+ ImGui::DragScalar("Roundness", ImGuiDataType_Float, &Opt->Roundness, 1, &RoundnessMin, &RoundnessMax, "%.3f");
+ if (ImGui::IsItemActive()) {
+ Memory->PurgeCache = true;
+ State->UpdateFrame = true;
+ }
// State->UpdateFrame = true;
}
ImGui::End();
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index 774b305..beb7c8f 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -786,7 +786,9 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
UI->CompPos.y + CompUV.y * UI->CompZoom.y);
shape_layer *Shape = &UI->Shape;
- ImGui::OpenPopupOnItemClick("shapecreate", ImGuiPopupFlags_MouseButtonRight);
+ if (Shape->Point_Count > 1) {
+ ImGui::OpenPopupOnItemClick("shapecreate", ImGuiPopupFlags_MouseButtonRight);
+ }
if (ImGui::BeginPopup("shapecreate")) {
if (ImGui::Selectable("Create shape layer")) {
State->HotkeyInput = hotkey_newlayer_shape;
diff --git a/src/include/functions.h b/src/include/functions.h
index 32737ea..2c18f85 100644
--- a/src/include/functions.h
+++ b/src/include/functions.h
@@ -18,6 +18,12 @@ static void Bezier_Interact_Evaluate(project_state *State, bezier_poin
static void Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation);
static void Bezier_Add(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *Block_Bezier_Count, uint16 *PointCount, bezier_point PointData);
+
+static uint32
+Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData,
+ project_state *State, layer_transforms T, int Width, int Height,
+ int CompWidth, int CompHeight, bool32 Interact);
+
void * Bezier_CubicCalcPoints(v2 p1, v2 p2, v2 p3, v2 p4, void *Data, uint32 Size);
static layer_transforms Transform_Inverse(layer_transforms T);
diff --git a/src/layer.cpp b/src/layer.cpp
index 6159467..b27935b 100644
--- a/src/layer.cpp
+++ b/src/layer.cpp
@@ -112,11 +112,14 @@ Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memor
Arbitrary_Zero((uint8 *)Data, sizeof(nvg_point) * 128);
layer_transforms T = Layer_GetTransforms(Layer);
v2 Min = {}, Max = {};
+ int ShapeWidth = 0, ShapeHeight = 0;
if (State->Interact_Active == interact_type_keyframe_move) {
NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, State, T, 0, 0, Width, Height, 0, &Min, &Max);
+ ShapeWidth = Max.x - Min.x;
+ ShapeHeight = Max.y - Min.y;
}
uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, (nvg_point *)Data,
- State, T, Shape->Width, Shape->Height, Width, Height, 1, &Min, &Max);
+ State, T, ShapeWidth, ShapeHeight, Width, Height, 1, &Min, &Max);
void *Data_Stroke = Memory_PushScratch(Memory, sizeof(real32) * 4 * 256);
uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, Shape->Opt.StrokeWidth, Shape->Opt.LineCapType, Shape->Opt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke);
void *Data_Fill = Memory_PushScratch(Memory, sizeof(real32) * 4 * NumberOfVerts);
diff --git a/src/nanovg.cpp b/src/nanovg.cpp
index 1fb59ee..22d8621 100644
--- a/src/nanovg.cpp
+++ b/src/nanovg.cpp
@@ -172,42 +172,28 @@ static real32 * NVG_ButtCap(nvg_point *Point, real32 *StrokeData,
// NOTE(fox): We only have to care about winding if we want to do HW accelerated
// shape subtraction with the stencil buffer (I think).
-// All the extra inputs on the second line are for when we need to take
-// interactive mode into account. Since undoing a transform requires knowledge
-// of the shape's size (does it?), the code needs to be ran twice, controlled
-// with the Interact bool.
static uint32
NVG_FlattenPath(memory *Memory, shape_layer *Shape, nvg_point *PointData,
project_state *State, layer_transforms T, int Width, int Height,
int CompWidth, int CompHeight, bool32 Interact, v2 *Min, v2 *Max)
{
nvg_point *PointPlayhead = PointData;
- for (int i = 0; i < Shape->Point_Count; i++) {
- bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+ bezier_point *BezierPointData = (bezier_point *)Memory_PushScratch(Memory, sizeof(bezier_point) * 128);
+ uint32 BezierCount = Bezier_Shape_Sort(Memory, Shape, BezierPointData,
+ State, T, Width, Height,
+ CompWidth, CompHeight, Interact);
+ for (int i = 0; i < BezierCount; i++) {
+ bezier_point *Point = &BezierPointData[i];
if (i == 0 || Point->Type == interpolation_type_linear) {
v2 Pos = Point->Pos[0];
- if (State->Interact_Active == interact_type_keyframe_move && Point->IsSelected && Interact != 0) {
- Pos = TransformPoint(T, Width, Height, Pos);
- Pos.x += State->Interact_Offset[0];
- Pos.y += State->Interact_Offset[1];
- Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
- }
*(v2 *)PointPlayhead = Pos;
if (Shape->IsClosed || (i != 0 && i != (Shape->Point_Count - 1))) {
PointPlayhead->Flags |= NVG_PT_CORNER;
}
PointPlayhead++;
} else if (Point->Type == interpolation_type_bezier) {
- bezier_point *Point_1 = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i-1, 1);
+ bezier_point *Point_1 = &BezierPointData[i-1];
v2 Pos[2] = { Point_1->Pos[0], Point->Pos[0] };
- if (State->Interact_Active == interact_type_keyframe_move && Point->IsSelected && Width != 0) {
- for (int i = 0; i < 2; i++) {
- Pos[i] = TransformPoint(T, Width, Height, Pos[i]);
- Pos[i].x += State->Interact_Offset[0];
- Pos[i].y += State->Interact_Offset[1];
- Pos[i] = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos[i].x, Pos[i].y);
- }
- }
PointPlayhead = (nvg_point *)Bezier_CubicCalcPoints(Pos[0], Pos[0] + Point_1->Pos[1], Pos[1] + Point->Pos[2], Pos[1], PointPlayhead, sizeof(nvg_point));
// The point at the end is also returned, so we remove it.
if (i != (Shape->Point_Count - 1))
@@ -216,6 +202,7 @@ NVG_FlattenPath(memory *Memory, shape_layer *Shape, nvg_point *PointData,
Assert(0);
}
}
+ Memory_PopScratch(Memory, sizeof(bezier_point) * 128);
int NumberOfVerts = PointPlayhead - PointData;
nvg_point *Point = &PointData[NumberOfVerts - 1];
nvg_point *NextPoint = PointData;