Author Topic: Polygon validation  (Read 1622 times)

0 Members and 1 Guest are viewing this topic.

Offline troflip

Polygon validation
« on: July 01, 2015, 10:31:45 AM »
In polygonedit.sc (Sierra's in-game polygon editor), there is a "check" method (which unfortunately my decompiler barfs on) that performs some validation on the created polygons. It removes duplicate points, for one. Then it also appears to perform some angle checks. I think it's verifying the exterior angles of the polygon add up to 360.

The thing is, I don't see how they couldn't, given that's a mathematical property of a polygon. Is it just detecting if there will be precision errors with the engine with certain sets of polygon points?

It also flips the order of the points of the polygon if the angles add up to -360 instead. But apparently Sierra's engine can handle either CW or CCW winding order, so I'm not sure why this is necessary.

Can anyone provide any insight?

fyi, here's a decompiled version of the code. Take with a grain of salt, since some of the branching is incorrect (I hacked my decompiler to just muddle through it):
Code: [Select]
    (method (check)
        (var _EditablePolygonFirst, temp1, curNode, nextNode, arcTan, arcTAnDiff, _EditablePolygonFirst_2, totalAngle, ccw, lastArcTan, _EditablePolygonLast, temp11, temp12, temp13, temp14, temp15, temp16, temp17[40])
        = _EditablePolygonFirst (self:first())
        (while (_EditablePolygonFirst)
            = curNode NodeValue(_EditablePolygonFirst)
            = temp15 NextNode(_EditablePolygonFirst)
            (while (temp15)
                = temp16 NodeValue(temp15)
                (if ((== (send temp2:x) (send temp16:x)) and (== (send temp2:y) (send temp16:y)))
                    = temp15 PrevNode(temp15)
                    (self:delete(temp16))
                    (send temp16:dispose())
                )
                = temp15 NextNode(temp15)
            )
            = _EditablePolygonFirst NextNode(_EditablePolygonFirst)
        )
        = arcTan 0
        = lastArcTan 0
        = totalAngle 0
        = ccw 1
        = _EditablePolygonFirst_2 (self:first())
        = _EditablePolygonFirst _EditablePolygonFirst_2
        (while (1)
            = curNode NodeValue(_EditablePolygonFirst)
            = temp1 (self:next(_EditablePolygonFirst))
            = nextNode NodeValue(temp1)
            = arcTan ATan((send curNode:x) (send curNode:y) (send nextNode:x) (send nextNode:y))
            (if (not ccw)
                = arcTAnDiff (- arcTan lastArcTan)
                (if (> arcTAnDiff 180)
                    = arcTAnDiff (- arcTAnDiff 360)
                )(else
                    (if (< arcTAnDiff -180)
                        = arcTAnDiff (+ arcTAnDiff 360)
                    )
                )
                = totalAngle (+ totalAngle arcTAnDiff)
            )
            = lastArcTan arcTan
            (== _EditablePolygonFirst _EditablePolygonFirst_2) and not ccw
        )
        (if (== type 3)
            = totalAngle neg totalAngle
        )
        (if (== totalAngle -360)
            = _EditablePolygonFirst (self:first())
            = _EditablePolygonLast (self:last())
            (while ((<> _EditablePolygonFirst _EditablePolygonLast) and (<> _EditablePolygonFirst NextNode(_EditablePolygonLast)))
                = temp2 NodeValue(_EditablePolygonFirst)
                = temp11 NodeValue(_EditablePolygonLast)
                = temp12 (send temp2:x)
                = temp13 (send temp2:y)
                (send temp2:x((send temp11:x)))
                (send temp2:y((send temp11:y)))
                (send temp11:x(temp12))
                (send temp11:y(temp13))
                = _EditablePolygonFirst NextNode(_EditablePolygonFirst)
                = _EditablePolygonLast PrevNode(_EditablePolygonLast)
            )
        )(else
            (if (<> totalAngle 360)
                Format(@temp17 943 1 name totalAngle)
                proc921_0(@temp17)
            )
        )
    )

And the (functionally accurate) disassembled version:

Code: [Select]

    (method (check)
        (var temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17[40])
        (asm
            pushi   #first
            pushi   0
            self    4
            sat     temp0
code_050c:  lat     temp0
            bnt     code_0575
            pushi   1
            push   
            callk   NodeValue, 2
            sat     temp2
            pushi   1
            lst     temp0
            callk   NextNode, 2
            sat     temp15
code_0520:  lat     temp15
            bnt     code_056b
            pushi   1
            push   
            callk   NodeValue, 2
            sat     temp16
            pushi   #x
            pushi   0
            lat     temp2
            send    4
            push   
            pushi   #x
            pushi   0
            lat     temp16
            send    4
            eq?     
            bnt     code_0561
            pushi   #y
            pushi   0
            lat     temp2
            send    4
            push   
            pushi   #y
            pushi   0
            lat     temp16
            send    4
            eq?     
            bnt     code_0561
            pushi   1
            lst     temp15
            callk   PrevNode, 2
            sat     temp15
            pushi   #delete
            pushi   1
            lst     temp16
            self    6
            pushi   #dispose
            pushi   0
            lat     temp16
            send    4
code_0561:  pushi   1
            lst     temp15
            callk   NextNode, 2
            sat     temp15
            jmp     code_0520
code_056b:  pushi   1
            lst     temp0
            callk   NextNode, 2
            sat     temp0
            jmp     code_050c
code_0575:  ldi     0
            sat     temp4
            ldi     0
            sat     temp9
            ldi     0
            sat     temp7
            ldi     1
            sat     temp8
            pushi   #first
            pushi   0
            self    4
            sat     temp6
            sat     temp0
code_058e:  ldi     1
            bnt     code_061d
            pushi   1
            lst     temp0
            callk   NodeValue, 2
            sat     temp2
            pushi   #next
            pushi   1
            lst     temp0
            self    6
            sat     temp1
            pushi   1
            push   
            callk   NodeValue, 2
            sat     temp3
            pushi   4
            pushi   #x
            pushi   0
            lat     temp2
            send    4
            push   
            pushi   #y
            pushi   0
            lat     temp2
            send    4
            push   
            pushi   #x
            pushi   0
            lat     temp3
            send    4
            push   
            pushi   #y
            pushi   0
            lat     temp3
            send    4
            push   
            callk   ATan, 8
            sat     temp4
            lat     temp8
            not     
            bnt     code_0602
            lst     temp4
            lat     temp9
            sub     
            sat     temp5
            push   
            ldi     180
            gt?     
            bnt     code_05eb
            lst     temp5
            ldi     360
            sub     
            sat     temp5
            jmp     code_05fb
code_05eb:  lst     temp5
            ldi     65356
            lt?     
            bnt     code_05fb
            lst     temp5
            ldi     360
            add     
            sat     temp5
code_05fb:  lst     temp7
            lat     temp5
            add     
            sat     temp7
code_0602:  lat     temp4
            sat     temp9
            lst     temp0
            lat     temp6
            eq?     
            bnt     code_0612
            lat     temp8
            not     
            bnt     code_0612
code_0612:  ldi     0
            sat     temp8
            lat     temp1
            sat     temp0
            jmp     code_058e
code_061d:  pTos    type
            ldi     3
            eq?     
            bnt     code_0629
            lat     temp7
            neg     
            sat     temp7
code_0629:  lst     temp7
            ldi     65176
            eq?     
            bnt     code_06b2
            pushi   #first
            pushi   0
            self    4
            sat     temp0
            pushi   #last
            pushi   0
            self    4
            sat     temp10
code_0640:  lst     temp0
            lat     temp10
            ne?     
            bnt     code_06d6
            lst     temp0
            pushi   1
            lst     temp10
            callk   NextNode, 2
            ne?     
            bnt     code_06d6
            pushi   1
            lst     temp0
            callk   NodeValue, 2
            sat     temp2
            pushi   1
            lst     temp10
            callk   NodeValue, 2
            sat     temp11
            pushi   #x
            pushi   0
            lat     temp2
            send    4
            sat     temp12
            pushi   #y
            pushi   0
            lat     temp2
            send    4
            sat     temp13
            pushi   #x
            pushi   1
            pushi   #x
            pushi   0
            lat     temp11
            send    4
            push   
            lat     temp2
            send    6
            pushi   #y
            pushi   1
            pushi   #y
            pushi   0
            lat     temp11
            send    4
            push   
            lat     temp2
            send    6
            pushi   #x
            pushi   1
            lst     temp12
            lat     temp11
            send    6
            pushi   #y
            pushi   1
            lst     temp13
            lat     temp11
            send    6
            pushi   1
            lst     temp0
            callk   NextNode, 2
            sat     temp0
            pushi   1
            lst     temp10
            callk   PrevNode, 2
            sat     temp10
            jmp     code_0640
            jmp     code_06d6
code_06b2:  lst     temp7
            ldi     360
            ne?     
            bnt     code_06d6
            pushi   5
            lea     @temp17
            push   
            pushi   943
            pushi   1
            pTos    name
            lst     temp7
            callk   Format, 10
            pushi   1
            lea     @temp17
            push   
            calle   TextPrint, 2
code_06d6:  ret     
        )
    )

« Last Edit: July 01, 2015, 10:39:51 AM by troflip »


Check out my website: http://icefallgames.com
Groundhog Day Competition


SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.122 seconds with 23 queries.