Einfaches Rag-Doll Verfahren

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Feindflug
Beiträge: 6
Registriert: 22.01.2014 15:11

Einfaches Rag-Doll Verfahren

Beitrag von Feindflug »

Hi Leute,
ich habe eine kleine Ragdollsimulation mittel PB geschrieben. Dabei habe ich versucht, die einzelnen Bestandteile mit den neuen Modulen zu kapseln. Zur Berechnung der Position mittels Beschleunigungsvariablen habe ich die Verlet Integration Variante gewählt, da sie stabiler ist, als Euler.

Grundsätzlicher Aufbau:
1. Primitives. Das sind Objekte, wie zum Beispiel Kugeln, oder Punkte.
2. Links: Das sind Verbindungen zwischen Primitiven. Diese haben eine Länge und eine Steifheit.
3. Entities: Entitites sind beliebige Kompositionen aus 1 und 2.
4. Hilfskram

Screenshot:
Bild

Code:

Code: Alles auswählen

EnableExplicit


;//////////////////////////////////////////////////////////
;// Math
;//////////////////////////////////////////////////////////

DeclareModule Math
    
    Declare.f fmax(val1.f, val2.f)
    Declare.f fmin(val1.f, val2.f)

EndDeclareModule

Module Math
    Procedure.f fmax(val1.f, val2.f)
        If (val1 < val2)
            ProcedureReturn val2
        Else
            ProcedureReturn val1
        EndIf
    EndProcedure
    
    Procedure.f fmin(val1.f, val2.f)
        If (val1 < val2)
            ProcedureReturn val1
        Else
            ProcedureReturn val2
        EndIf
    EndProcedure
    
EndModule

DeclareModule Vector2
    Structure Type
        x.f
        y.f
    EndStructure
    
    Structure TypeInt
        x.i
        y.i
    EndStructure
    
    Declare.f dot(*vector.Type)
    Declare.f length(*vector.Type)
    Declare   normalize(*vector.Type)
    
    Macro ADD(__RESULT, __VEC1, __VEC2)
        __RESULT\x = __VEC1\x + __VEC2\x
        __RESULT\y = __VEC1\y + __VEC2\y
    EndMacro
    
    Macro ADDSCALAR(__RESULT, __VEC1, __SCALAR)
        __RESULT\x = __VEC1\x + __SCALAR
        __RESULT\y = __VEC1\y + __SCALAR
    EndMacro
    
    
    Macro SUB(__RESULT, __VEC1, __VEC2)
        __RESULT\x = __VEC1\x - __VEC2\x
        __RESULT\y = __VEC1\y - __VEC2\y
    EndMacro
    
    Macro SUBSCALAR(__RESULT, __VEC1, __SCALAR)
        __RESULT\x = __VEC1\x - __SCALAR
        __RESULT\y = __VEC1\y - __SCALAR
    EndMacro
    
    Macro MULSCALAR(__RESULT, __VEC1, __SCALAR)
        __RESULT\x = __VEC1\x * __SCALAR
        __RESULT\y = __VEC1\y * __SCALAR
    EndMacro
    
    Macro DIVSCALAR(__RESULT, __VEC1, __SCALAR)
        If (__SCALAR <> 0.0)
            __RESULT\x = __VEC1\x / __SCALAR
            __RESULT\y = __VEC1\y / __SCALAR
        EndIf
    EndMacro
    
    Macro ASSIGN(__DEST, __SOURCE)
        __DEST\x = __SOURCE\x
        __DEST\y = __SOURCE\y
    EndMacro
    
    Macro CREATE(__NAME, __X, __Y)
        Define.Vector2::Type __NAME
        __NAME\x = __X
        __NAME\y = __Y
    EndMacro
    
    Macro CREATEINT(__NAME, __X, __Y)
        Define.Vector2::TypeInt __NAME
        __NAME\x = __X
        __NAME\y = __Y
    EndMacro
    
    Macro CREATECOPY(__NAME, __OTHER)
        Define.Vector2::Type __NAME
        __NAME\x = __OTHER\x
        __NAME\y = __OTHER\y
    EndMacro
    
EndDeclareModule

Module Vector2
    
    
    Procedure.f dot(*vector.Type)
        ProcedureReturn *vector\x * *vector\x + *vector\y * *vector\y
    EndProcedure
    
    Procedure.f length(*vector.Type)
        ProcedureReturn Sqr(dot(*vector))
    EndProcedure
    
    Procedure normalize(*vector.Type)
        Define.f vecLength = length(*vector)
        DIVSCALAR(*vector, *vector, vecLength)
    EndProcedure

EndModule

;//////////////////////////////////////////////////////////
;// Screen
;//////////////////////////////////////////////////////////

DeclareModule Screen
    
    Macro TRANSFORM2SCREEN(__RESULT, __SOURCE)
        __RESULT\x = Int(__SOURCE\x * ScreenWidth())
        __RESULT\y = Int(__SOURCE\y * ScreenHeight())
    EndMacro
    
    Macro TRANSFORM2WORLD(__RESULT, __SOURCE)
        __RESULT\x = __SOURCE\x / ScreenWidth()
        __RESULT\y = __SOURCE\y / ScreenHeight()
    EndMacro
    
    
EndDeclareModule


Module Screen
EndModule

;//////////////////////////////////////////////////////////
;// Primitives
;//////////////////////////////////////////////////////////

DeclareModule Primitive
    
    Prototype protDrawPrimitive(*primitive)
    Prototype protConstraint(*primitive)
    Prototype protIntegrate(*primitive, elapsedTime.d, dT.d)
    
    Structure Type
        oldPosition.Vector2::Type
        position.Vector2::Type
        fixed.b
        
        draw.protDrawPrimitive
        constraint.protConstraint
        integrate.protIntegrate
    EndStructure
    
    Macro FILL(__PRIMITIVE, __POSITION, __FIXED, __DRAWSTRATEGY, __CONSTRAINT, __INTEGRATE)
        Vector2::ASSIGN(__PRIMITIVE\oldPosition, __POSITION)
        Vector2::ASSIGN(__PRIMITIVE\position, __POSITION)
        __PRIMITIVE\fixed = __FIXED
        __PRIMITIVE\draw = __DRAWSTRATEGY
        __PRIMITIVE\constraint = __CONSTRAINT
        __PRIMITIVE\integrate = __INTEGRATE
    EndMacro
    
    Declare drawPrimitiveCircle(*primitive.Type)
    Declare boxedConstraint(*primitive.Type)
    Declare gravityIntegration(*primitive.Type, elapsedTime.d, dT.d)
    
EndDeclareModule


Module Primitive
    
    Procedure gravityIntegration(*primitive.Type, elapsedTime.d, dT.d)
        If *primitive\fixed = #True
            *primitive\position = *primitive\oldPosition
            ProcedureReturn
        EndIf
        
        Define.Vector2::Type newPosition
        Vector2::ASSIGN(newPosition, *primitive\position)
        Vector2::MULSCALAR(newPosition, newPosition, 2)
        Vector2::SUB(newPosition, newPosition, *primitive\oldPosition)
        
        Vector2::CREATE(gravity, 0.0, 9.81)
        Define.f dT2 = dT * dT
        Vector2::MULSCALAR(gravity, gravity, dT * dT)
        
        Vector2::ADD(newPosition, newPosition, gravity)
        
        Vector2::ASSIGN(*primitive\oldPosition, *primitive\position)
        Vector2::ASSIGN(*primitive\position, newPosition)
    EndProcedure
    
    
    Procedure boxedConstraint(*primitive.Type)
        Define.Vector2::Type *position = @*primitive\position
        
        *position\x = Math::fmax(0.0, *position\x)
        *position\y = Math::fmax(0.0, *position\y)
         
        *position\x = Math::fmin(1.0, *position\x)
        *position\y = Math::fmin(1.0, *position\y)
        
    EndProcedure
    
    
    Procedure drawPrimitiveCircle(*primitive.Type)
        Define.Vector2::TypeInt screenVec
        Screen::TRANSFORM2SCREEN(screenVec, *primitive\position)
        Define.Vector2::Type testVec
        Vector2::ASSIGN(testVec, *primitive\position)
        Screen::TRANSFORM2SCREEN(testVec, *primitive\position)
        
        Circle(screenVec\x, screenVec\y, 4, RGB(255,255,255))    
    EndProcedure
    
EndModule

;//////////////////////////////////////////////////////////
;// Links 
;//////////////////////////////////////////////////////////

DeclareModule Link
    
    Prototype protDrawLink(*Link)
    Prototype protConstraint(*Link)
    
    Structure Type
        *from.Primitive::Type
        *to.Primitive::Type
        
        distance.f
        damping.f
        
        draw.protDrawLink
        constraint.protConstraint
    EndStructure
    
    Macro FILL(__LINK, __FROM, __TO, __DISTANCE, __DAMPING, __DRAWSTRATEGY, __CONSTRAINT)
        __LINK\from = __FROM
        __LINK\to = __TO
        __LINK\distance = __DISTANCE
        __LINK\draw = __DRAWSTRATEGY
        __LINK\constraint = __CONSTRAINT
        __LINK\damping = __DAMPING
    EndMacro
    
    Declare drawLinkLine(*link)
    
    Declare constraintElastic(*link)
    
EndDeclareModule


Module Link
    
    Procedure drawLinkLine(*link.Link::Type)
        Define.Vector2::Type fromPos
        Screen::TRANSFORM2SCREEN(fromPos, *link\from\position)
        Define.Vector2::Type toPos
        Screen::TRANSFORM2SCREEN(toPos, *link\to\position)
        
        LineXY(fromPos\x, fromPos\y, toPos\x, toPos\y, RGB(150,150,150))     
        
    EndProcedure
    
    Procedure constraintElastic(*link.Link::Type)
        Define.Vector2::Type *fromPos = @*link\from\position
        Define.Vector2::Type *toPos = @*link\to\position
        
        ;CallDebugger
        
        Define.Vector2::Type difference
        Vector2::SUB(difference, *toPos, *fromPos)
        
        Define.f dDist = Vector2::length(difference) - *link\distance
        dDist * *link\damping
        dDist * 0.5
        
        Vector2::normalize(@difference)
        Vector2::MULSCALAR(difference, difference, dDist)
        
        If (*link\to\fixed = #False)
            Vector2::SUB(*toPos, *toPos, difference)
        EndIf
        
        If (*link\from\fixed = #False)
            Vector2::ADD(*fromPos, *fromPos, difference)
        EndIf
        
    EndProcedure
    
    
EndModule

;//////////////////////////////////////////////////////////
;// Entity
;//////////////////////////////////////////////////////////

DeclareModule Entity
    
    Prototype protDrawEntity(*entity)
    Prototype protUpdateConstraint(*entity)
    Prototype protIntegrate(*entity, elapsedTime.d, dT.d) 
    
    Structure Container
        Array linkList.Link::Type(1)
        Array primitiveList.Primitive::Type(1)
    EndStructure
    
    Structure Type
        *data.Container
        
        draw.protDrawEntity
        update.protUpdateConstraint
        integrate.protIntegrate
    EndStructure
    
    Declare defaultDraw(*entity.Type)
    Declare defaultConstraint(*entity.Type)
    Declare defaultIntegrate(*entity.Type, elapsedTime.d, dT.d)
    
    Declare createNet(*newEntity.Type, *min.Vector2::Type, *max.Vector2::Type, *dimension.Vector2::TypeInt)
    
EndDeclareModule


Module Entity
    
    Procedure defaultIntegrate(*entity.Type, elapsedTime.d, dT.d)
        Define.Entity::Container *container = *entity\data
        Define.i arrSize = ArraySize(*container\primitiveList())
        For i = 0 To arrSize
            *container\primitiveList(i)\Integrate(*container\primitiveList(i), elapsedTime, dT)
        Next
            
    EndProcedure
    
    
    Procedure defaultConstraint(*entity.Type)
        Define.Entity::Container *container = *entity\data
        Define.i iterations = 2*Int(Sqr(ArraySize(*container\linkList())))+1
        
        For i=0 To iterations
            Define.i arrSize = ArraySize(*container\linkList())
            For i = 0 To arrSize
                *container\linkList(i)\constraint(*container\linkList(i))
            Next
            
            arrSize = ArraySize(*container\primitiveList())
            For i = 0 To arrSize
                *container\primitiveList(i)\constraint(*container\primitiveList(i))
            Next
        Next
        
    EndProcedure
    
    
    Procedure defaultDraw(*entity.Type)
        Define.Entity::Container *container = *entity\data
        Define.i arrSize
        
        ;CallDebugger
        arrSize = ArraySize(*container\linkList())
        For i = 0 To arrSize
            *container\linkList(i)\draw(*container\linkList(i))
        Next
        
        arrSize = ArraySize(*container\primitiveList())
        For i = 0 To arrSize
            *container\primitiveList(i)\draw(*container\primitiveList(i))
        Next
        
    EndProcedure
    
    
    Procedure createNet(*newEntity.Type, *min.Vector2::Type, *max.Vector2::Type, *dimension.Vector2::TypeInt)
        
        *data.Container = AllocateMemory(SizeOf(Container))
        InitializeStructure(*data, Container)
        *newEntity\data = *data
        *newEntity\draw = Entity::@defaultDraw()
        *newEntity\update = Entity::@defaultConstraint()
        *newEntity\integrate = Entity::@defaultIntegrate()
        Define.Vector2::TypeInt reducedDim
        Vector2::SUBSCALAR(reducedDim, *dimension, 1)
        
        Define.i size = *dimension\x * *dimension\y
        Define.i linkSize = *dimension\x * *dimension\y * 2 - *dimension\x - *dimension\y
        ReDim *data\linkList(linkSize - 1)
        ReDim *data\primitiveList(size - 1)
        
        Define.Vector2::Type netSize
        Vector2::SUB(netSize, *max, *min)
        
        Define.f dX = netSize\x / reducedDim\x
        Define.f dY = netSize\y / reducedDim\y
        
        Define.i offset = 0
        For y = 0 To reducedDim\y
            For x = 0 To reducedDim\x
                
                Vector2::CREATE(primPos, x * dX, y * dY)
                Vector2::ADD(primPos, primPos, *min)
                Define fixed = Bool(y=0)
                
                Primitive::FILL(*Data\primitiveList(offset),
                                primPos, 
                                fixed, 
                                Primitive::@drawPrimitiveCircle(),
                                Primitive::@boxedConstraint(),
                                Primitive::@gravityIntegration())
                
                offset + 1
            Next
            
        Next
        
        Define.i counter = 0
        For y = 0 To reducedDim\y
            For x = 0 To reducedDim\x
                
                offset = x + y * *dimension\x
                If (y <> reducedDim\y)
                    Link::FILL(*data\linkList(counter), 
                               *data\primitiveList(offset), 
                               *data\primitiveList(offset+*dimension\y), 
                               dY, 
                               1.0, 
                               Link::@drawLinkLine(), 
                               Link::@constraintElastic())
                    counter+1    
                EndIf
                
                If (x <> reducedDim\x)
                    Link::FILL(*data\linkList(counter), 
                               *data\primitiveList(offset), 
                               *data\primitiveList(offset+1), 
                               dX, 
                               0.3, 
                               Link::@drawLinkLine(), 
                               Link::@constraintElastic())
                    counter+1    
                EndIf
            Next
        Next
    EndProcedure

EndModule


;//////////////////////////////////////////////////////////
;// Main
;//////////////////////////////////////////////////////////

DeclareModule Main
    
    Declare start()
    
EndDeclareModule


Module Main
    
    Global NewList entityList.Entity::Type()
    
    Global.i running = #True
    
    Global elapsedTime.d

    Procedure init()
        InitSprite()
        OpenWindow(0, 0, 0, 600, 400, "Ragdoll", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
        OpenWindowedScreen(WindowID(0), 0, 0, 600, 400)
        
        ;CallDebugger
        
        Vector2::CREATE(netMin, 0.2, 0.2)
        Vector2::CREATE(netMax, 0.8, 0.8)
        Vector2::CREATEINT(dimension, 10, 10)
        AddElement(entityList())
        
        Entity::createNet(entityList(), @netMin, @netMax, @dimension)
        
    EndProcedure
    
    
    Procedure draw()
        
        ClearScreen(RGB(0,0,0))
        StartDrawing(ScreenOutput())
        
        ForEach entityList()
            entityList()\draw(entityList())
        Next
        
        StopDrawing()
        FlipBuffers()
    EndProcedure
    

    Procedure processWindowEvent()
        Define.i event = #PB_Event_None
        Repeat
            event = WindowEvent()

            Select event
                Case #PB_Event_None:
                    ;onIdle()
                    
                Case #PB_Event_CloseWindow:
                    running = false
            EndSelect
        Until event = #PB_Event_None
    EndProcedure
    

    Procedure update()
        Define.d currentTime = ElapsedMilliseconds() * 0.001
        If elapsedTime = 0.0
            elapsedTime = currentTime
        EndIf
        
        Define.d dT = currentTime - elapsedTime
        
        ForEach entityList()
            entityList()\integrate(entityList(), currentTime, dT)
            entityList()\update(entityList())
        Next
        
        elapsedTime = currentTime
    EndProcedure
    
    
    Procedure user()
        ForEach entityList()
            Define.Entity::Container *dataContainer = entityList()\data
            
            Define.i arrSize = ArraySize(*dataContainer\primitiveList())
            For i = 0 To arrSize - 1
                Define.Vector2::Type *position = @*dataContainer\primitiveList(i)\position
                
                Vector2::CREATE(mouse, WindowMouseX(0), WindowMouseY(0))
                Screen::TRANSFORM2WORLD(mouse, mouse)
                
                Vector2::CREATECOPY(difference, mouse)
                Vector2::SUB(difference, difference, *position)
                
                Define.f distance = Vector2::length(difference)
                If (distance < 0.2)
                    distance = 0.2 - distance
                    distance * 0.1
                    Vector2::normalize(difference)
                    Vector2::MULSCALAR(difference, difference, distance)
                    Vector2::SUB(*position, *position, difference)
                EndIf
            Next
            
        Next
            
    EndProcedure
    
    
    Procedure done()
    EndProcedure
    
    
    Procedure start()
        init()
        
        While (running)
            processWindowEvent()
            update()
            draw()
            user()
        Wend
        
        done()
    EndProcedure
    
EndModule

;//////////////////////////////////////////////////////////
;// START
;//////////////////////////////////////////////////////////


Main::start()
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: Einfaches Rag-Doll Verfahren

Beitrag von Kukulkan »

Toll, macht Spaß :-)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Einfaches Rag-Doll Verfahren

Beitrag von NicTheQuick »

Vielleicht hab ich den Codeteil dafür nicht gefunden, aber wieso zappelt und springt das Teil auch herum, wenn ich gar nichts mache? :|
Und dann noch zwei Kleinigkeiten:

Code: Alles auswählen

    Macro ASSIGN(__DEST, __SOURCE)
        __DEST\x = __SOURCE\x
        __DEST\y = __SOURCE\y
    EndMacro
Das brauchst du eigentlich nicht, da man in PB seit kurzem strukturierte Variablen auch einfach so kopieren kann.

Zweitens: Dein 'Vector2::CREATE' macht zwar ein 'Define', aber nicht das für Procedures eigentlich gedachte 'Protected'. Wenn man also nicht aufpasst, könnte man aus Versehen eine gleichnamige globale Variable in einer Procedure benutzen wollen und bekommt dann den Fehler "[COMPILER] Line 3: Variable already declared with a different scope: a.", wie man an diesem Beispiel sieht:

Code: Alles auswählen

Global a.l = 2
Procedure test()
	Define a.l = 1
	Debug a
EndProcedure

Debug a
test()
Debug a
Aber sonst sieht es schon gut aus. :allright:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Einfaches Rag-Doll Verfahren

Beitrag von ts-soft »

:allright: gefällt mir!

Kleiner Hinweis noch, Dein EnableExplicit wirkt sich nur auf die letzte Zeile aus, das ist in den Modulen nicht gültig!
(dann fällt unter anderem auf, das bei false ein # fehlt :wink: )

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Feindflug
Beiträge: 6
Registriert: 22.01.2014 15:11

Re: Einfaches Rag-Doll Verfahren

Beitrag von Feindflug »

NicTheQuick hat geschrieben:Vielleicht hab ich den Codeteil dafür nicht gefunden, aber wieso zappelt und springt das Teil auch herum, wenn ich gar nichts mache? :|
Ich nutze den Zeitunterschied zum letzten Frame. Wenn Du jetzt das Fenster verschiebst, springt es exorbitant durch die Gegend.
Wenn nun im Hintergrund Prozesse laufen, die das Programm zu lange ruhen lassen, dann kann es dadurch zum Zittern kommen.
NicTheQuick hat geschrieben:Das brauchst du eigentlich nicht, da man in PB seit kurzem strukturierte Variablen auch einfach so kopieren kann.
Gut zu wissen. Gibts dafür einen Extra-Befehl oder reicht der operator= ?

NicTheQuick hat geschrieben:Zweitens: Dein 'Vector2::CREATE' macht zwar ein 'Define', aber nicht das für Procedures eigentlich gedachte 'Protected'. Wenn man also nicht aufpasst, könnte man aus Versehen eine gleichnamige globale Variable in einer Procedure benutzen wollen und bekommt dann den Fehler "[COMPILER] Line 3: Variable already declared with a different scope: a.", wie man an diesem [...]
Guter Hinweis. Danke.
NicTheQuick hat geschrieben:Aber sonst sieht es schon gut aus. :allright:
Danke schön.

@ts-soft:
Danke für den Hinweis. Ist mir auch schon aufgefallen, dass EnableExplicit nicht keine Auswirkungen auf Module hatte und dachte, es wäre ein Bug ^___^.


Danke für euer Feedback.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Einfaches Rag-Doll Verfahren

Beitrag von ts-soft »

Feindflug hat geschrieben:@ts-soft:
Danke für den Hinweis. Ist mir auch schon aufgefallen, dass EnableExplicit nicht keine Auswirkungen auf Module hatte und dachte, es wäre ein Bug ^___^.
Nein, das ist ein Feature :wink: Das EnableExplicit gehört in jedem Module-Abschnitt, ansonsten würde es ja auch keinen Sinn machen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Einfaches Rag-Doll Verfahren

Beitrag von NicTheQuick »

Also ausgelastet ist bei mir wirklich wenig, vielleicht ist mein Rechner auch einen Tacken zu schnell und deswegen sind die Millisekunden zwischen einzelnen Frames auch 0, ich weiß es nicht genau. Hab's nicht weiter untersucht. Aber hier ist mal ein Video wie es bei mir aussieht.
Purebasic Rag-Doll-Test
Benutzeravatar
Feindflug
Beiträge: 6
Registriert: 22.01.2014 15:11

Re: Einfaches Rag-Doll Verfahren

Beitrag von Feindflug »

NicTheQuick: Ich vermute den "Fehler" beim ElapsedMilliseconds()-Befehl. Der scheint mir arg grob zu sein ;-)

Des weiteren müsste ich die Updates des Gitters mit der abgelaufenen Zeitspanne synchronisieren.
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Einfaches Rag-Doll Verfahren

Beitrag von bobobo »

nice
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Antworten