Skip to content

Commit cc20ee7

Browse files
HarrievGRobertBeckebans
authored andcommitted
Fixed swf line drawing.
Please note: Only supporting round joints and caps, like < SWF 8
1 parent 899328c commit cc20ee7

File tree

2 files changed

+116
-55
lines changed

2 files changed

+116
-55
lines changed

neo/swf/SWF_ShapeParser.cpp

Lines changed: 115 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,43 @@ If you have questions concerning this license or the applicable additional terms
3333
#pragma warning( disable: 4189 ) // local variable is initialized but not referenced
3434

3535
// HarrievG begin
36-
void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld, swfSPMorphEdge_t& edge, bool end )
36+
void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld, swfSPMorphEdge_t& edge, bool start )
3737
{
3838
//figure out what the orientation of the cap is.
39+
uint16 v0StartIndex = edge.start.v0;
40+
uint16 v1StartIndex = ( edge.start.cp == 0xFFFF ) ? edge.start.v1 : edge.start.cp;
3941

40-
idVec2 up = ( verts[edge.start.v0] - verts[edge.start.v1] );
41-
idVec2 down = ( verts[edge.end.v1] - verts[edge.end.v0] );
42+
uint16 v0EndIndex = ( edge.end.cp == 0xFFFF ) ? edge.end.v0 : edge.end.cp;
43+
uint16 v1EndIndex = edge.end.v1;
44+
45+
uint16 v0 = v0StartIndex;
46+
uint16 v1 = v1StartIndex;
47+
48+
if( !start )
49+
{
50+
v0 = v0EndIndex;
51+
v1 = v1EndIndex;
52+
}
53+
54+
idVec2 up = ( verts[v0] - verts[v1] );
55+
idVec2 down = ( verts[v1] - verts[v0] );
4256
idVec2 cross = idVec2( down.y, -down.x );
4357
idVec2 crossUp = idVec2( up.y, -up.x );
4458

4559
uint8 vertIndex;
46-
if( end )
60+
if( !start )
4761
{
48-
vertIndex = edge.start.v1;
62+
vertIndex = v1;
4963
}
5064
else
5165
{
52-
vertIndex = edge.start.v0;
66+
vertIndex = v0;
5367
cross = crossUp;
5468
}
5569

70+
float scale = ( float )( 1.0f / 20 ) * ( ld.style.startWidth * 0.5 ) ;
71+
72+
//vert
5673
int capCenterIdx = ld.startVerts.AddUnique( verts[vertIndex] );
5774
int pointCnt;
5875
float x, z;
@@ -62,42 +79,28 @@ void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFSh
6279
float angle = idMath::ATan( xup.y - cross.y, xup.x - cross.x ) + idMath::PI;
6380

6481
idMath::SinCos( angle, s, c );
65-
float scale = ( float ) ld.style.startWidth / 40;
82+
6683
matrix.xx = c * scale;
6784
matrix.yx = s * scale;
6885
matrix.xy = -s * scale;
6986
matrix.yy = c * scale;
7087
int A, B;
71-
for( float w = 0.0; w <= 180 ; w += 10 )
88+
for( float w = -10; w <= 180 + 10; w += 10 )
7289
{
73-
74-
if( !w )
75-
{
76-
idMath::SinCos( DEG2RAD( w ), z, x );
77-
}
78-
else
79-
{
80-
idMath::SinCos( DEG2RAD( w ), z, x );
81-
}
90+
idMath::SinCos( DEG2RAD( w ), z, x );
8291

8392
ld.indices.Append( capCenterIdx );
8493
A = ld.startVerts.AddUnique( matrix.Transform( idVec2( x, z ) ) + ld.startVerts[capCenterIdx] );
8594

86-
if( w > 10 )
95+
if( w >= 0.0f )
8796
{
8897
ld.indices.Append( B );
8998
ld.indices.Append( A );
9099
ld.indices.Append( capCenterIdx );
91-
92-
}
93-
else if( w + 10 <= 180 )
94-
{
95-
w += 10;
96100
}
97101

98102
ld.indices.Append( A );
99103

100-
101104
idMath::SinCos( DEG2RAD( w ), z, x );
102105
B = ld.startVerts.AddUnique( matrix.Transform( idVec2( x , z ) ) + ld.startVerts[capCenterIdx] );
103106
ld.indices.Append( B );
@@ -148,36 +151,55 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int
148151
for( int e = 0; e < spld.edges.Num(); e++ )
149152
{
150153
//startcap
151-
if( ld.style.startCapStyle == 0 && ld.style.startWidth > 60 && spld.edges.Num() )
154+
//only supporting round
155+
if( ld.style.startCapStyle == 0 )
152156
{
153-
MakeCap( spld, ld, spld.edges[e], false );
157+
MakeCap( spld, ld, spld.edges[e], true );
154158
}
155-
//joint.
156-
idVec2 up = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] );
157-
idVec2 down = ( verts[ spld.edges[e].start.v1 ] - verts[ spld.edges[e].start.v0 ] );
159+
160+
uint16 v0StartIndex = spld.edges[e].start.v0;
161+
uint16 v1StartIndex = ( spld.edges[e].start.cp == 0xFFFF ) ? spld.edges[e].start.v1 : spld.edges[e].start.cp;
162+
163+
uint16 v0EndIndex = ( spld.edges[e].end.cp == 0xFFFF ) ? spld.edges[e].end.v0 : spld.edges[e].end.cp;
164+
uint16 v1EndIndex = spld.edges[e].end.v1;
165+
166+
uint16 v0 = v0StartIndex;
167+
uint16 v1 = v1StartIndex;
168+
169+
idVec2 up = ( verts[v0] - verts[v1] );
170+
idVec2 down = ( verts[v1] - verts[v0] );
158171
idVec2 cross = idVec2( down.y, -down.x );
159172
idVec2 crossUp = idVec2( up.y, -up.x );
160-
idVec2 offSetA = crossUp * ( ( 1.0f / down.Length() ) * ld.style.startWidth / 20 );
161-
idVec2 offSetB = cross * ( ( 1.0f / down.Length() ) * ld.style.startWidth / 40 );
162173

163-
int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetB );
164-
int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetA + offSetB );
165-
ld.indices.Append( v0 );
174+
float scale = ( float )( 1.0f / 20 ) * ( ld.style.startWidth * 0.5 );
175+
176+
idVec2 offSetA = crossUp * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f ;
177+
idVec2 offSetB = cross * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f;
178+
179+
v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] - offSetB );
180+
int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] - offSetA );
181+
182+
//straight line
166183
if( spld.edges[e].start.cp == 0xFFFF )
167184
{
185+
ld.indices.Append( v0 );
168186
ld.indices.Append( v0x );
169187
}
170-
int last = v0x;
188+
171189
// Rather then tesselating curves at run time, we do them once here by inserting a vert every 10 units
172190
// It may not wind up being 10 actual pixels when rendered because the shape may have scaling applied to it
173191
if( spld.edges[e].start.cp != 0xFFFF )
174192
{
175193
assert( spld.edges[e].end.cp != 0xFFFF );
176-
float length1 = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ).Length();
177-
float length2 = ( verts[ spld.edges[e].end.v0 ] - verts[ spld.edges[e].end.v1 ] ).Length();
194+
float length1 = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ).Length() * scale;
195+
float length2 = ( verts[ spld.edges[e].end.v0 ] - verts[ spld.edges[e].end.v1 ] ).Length() * scale;
178196
int numPoints = 1 + idMath::Ftoi( Max( length1, length2 ) / 10.0f );
179197
int lastV1;
180-
int lastV2;
198+
int last;
199+
v0 = ld.startVerts.AddUnique( verts[spld.edges[e].end.v0] + offSetB );
200+
v0x = ld.startVerts.AddUnique( verts[spld.edges[e].end.v0] + offSetA );
201+
ld.indices.Append( v0 );
202+
181203
for( int ti = 0; ti < numPoints; ti++ )
182204
{
183205
float t0 = ( ti + 1 ) / ( ( float ) numPoints + 1.0f );
@@ -204,45 +226,84 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int
204226
idVec2 idown = p2 - p1;
205227
idVec2 icross = idVec2( idown.y, -idown.x );
206228
idVec2 icrossUp = idVec2( iup.y, -iup.x );
207-
idVec2 ioffSetA = icrossUp * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 20 );
208-
idVec2 ioffSetB = icross * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 40 );
229+
idVec2 ioffSetA = icrossUp * ( ( ( 1.0f / 20 ) / idown.Length() ) * ld.style.startWidth ) * 0.5f;
230+
idVec2 ioffSetB = icross * ( ( ( 1.0f / 20 ) / idown.Length() ) * ld.style.startWidth ) * 0.5f;
209231

210-
int v1 = ld.startVerts.AddUnique( p1 + ioffSetB ) ;
211-
int v2 = ld.startVerts.AddUnique( p1 + ioffSetA + ioffSetB ) ;
232+
v1 = ld.startVerts.AddUnique( p1 + ioffSetB );
233+
int v2 = ld.startVerts.AddUnique( p1 + ioffSetA );
212234

213235
if( ti > 0 )
214236
{
215237
ld.indices.Append( v2 );
216238
ld.indices.Append( lastV1 );
217239
}
218240

219-
if( ti == 0 )
220-
{
221-
ld.indices.Append( v2 );
222-
}
223241
ld.indices.Append( v1 );
224242
ld.indices.Append( v2 );
225243
if( ti > 0 )
226244
{
227245
ld.indices.Append( v2 );
246+
ld.indices.Append( v1 );
247+
}
248+
else
249+
{
250+
ld.indices.Append( v2 );
251+
}
252+
253+
if( ti == numPoints - 1 )
254+
{
255+
ld.indices.Append( v2 );
256+
}
257+
258+
if( ti == 0 )
259+
{
260+
261+
ld.indices.Append( v0 );
262+
ld.indices.Append( v0x );
263+
ld.indices.Append( v1 );
264+
ld.indices.Append( v2 );
228265
}
229-
ld.indices.Append( v1 );
230266

231-
lastV2 = v2;
232267
lastV1 = v1;
233268
last = v2;
234269
}
270+
271+
v0 = v0EndIndex;
272+
v1 = v1EndIndex;
273+
274+
up = ( verts[v0] - verts[v1] );
275+
down = ( verts[v1] - verts[v0] );
276+
cross = idVec2( down.y, -down.x );
277+
crossUp = idVec2( up.y, -up.x );
278+
279+
offSetA = crossUp * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f;
280+
offSetB = cross * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f;
281+
282+
283+
ld.indices.Append( lastV1 );
284+
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] + offSetA ) );
285+
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] + offSetB ) );
286+
287+
ld.indices.Append( last );
288+
ld.indices.Append( lastV1 );
289+
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] + offSetA ) );
235290
}
236-
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB ) );
237-
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetA + offSetB ) );
238-
ld.indices.Append( last );
239-
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB ) );
291+
else
292+
{
293+
//straight line
294+
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] - offSetB ) );
295+
296+
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] - offSetA ) );
297+
ld.indices.Append( v0x );
298+
ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] - offSetB ) );
299+
}
300+
240301
last = ld.indices.Num() - 1;
241302

242303
//endcap
243-
if( ld.style.endCapStyle == 0 && ld.style.startWidth > 60 )
304+
if( ld.style.endCapStyle == 0 )
244305
{
245-
MakeCap( spld, ld, spld.edges[e], true );
306+
MakeCap( spld, ld, spld.edges[e], false );
246307
}
247308
}
248309
}

neo/swf/SWF_ShapeParser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class idSWFShapeParser
9090
void TriangulateSoup( idSWFFontGlyph& shape );
9191
int FindEarVert( const swfSPLineLoop_t& loop );
9292
void AddUniqueVert( idSWFShapeDrawFill& drawFill, const idVec2& start, const idVec2& end );
93-
void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool end ); // HarrievG
93+
void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool start );
9494
};
9595

9696
#endif // !__SWF_SHAPEPARSER_H__

0 commit comments

Comments
 (0)