Tricks, die ich meine zu kennen



  • Wollten wir denn nicht alle, wissen, wie die das ganze "magische" Zeug
    machen?
    Es ist anscheinend garnicht so schwer, wenn man die Tricks kennt.
    Man sollte C und Assembler lernen und die Tricks kennen.
    Ich glaube, ich habe jetzt soweit alles geblickt.

    Was braucht man?

    1. 3D-Grafik

    Nur das Licht, das vom Objektpunkt durch einen Projektionspunkt gelangt,
    gelangt im entsprechenden Steigungswinkel auf die hinter dem
    Projektionspunkt liegenden Projektionsflaeche. Das Licht breitet sich
    stets punktfoermig aus, aber auf der Netzhaut landet nur das Licht,
    das gedanklich vom Objektpunkt durch eine kleine Durchgangsoeffnung
    gelangt. Dafuer braucht der Lichtstrahl einen bestimmten Winkel.
    Vergleiche: Camera Obscura.
    Das heisst, man teilt x und y-Koordinaten des Objektpunkts durch die
    z-Entfernung und subtrahiert das Ergebnis von den Koordinaten der
    Bildschirmmitte, um die Koordinaten des Punkts auf dem Screen zu erhalten.
    So erklaert sich die Fluchtpunktperspektive bei der Zentralprojektion.
    Raytracing geht durch rekursive Punktfoermige Ausbreitung von der Licht-
    quelle zu Objektpunkten und von denen weiter punktfoermig und so fort.
    Wird aber selten korrekt und vollstaendig gemacht, da es einen Haufen
    Rechenleistung benoetigt.
    Bei Drehungen dreht man die Welt in entgegengesetzter Richtung der
    Kamera um die Koordinatenachsen, um die Kamera zu drehen und die Pixel-
    gruppen fuer die Objektdarstellung _vor_ der Projektion nacheinander um
    die Koordinatenachsen, wobei man mit drei Bezugspunkten den Drehwinkel
    anhand einer fixen Koordinate bestimmt (man probiert Drehwinkel durch und wählt die größte Annäherung).
    Fuer Drehungen gibt es einfache Kreisformeln, die Teil vom Schulstoff
    sind. Man sollte aber die Werte in einer Tabelle abspeichern, weil die
    Berechnung von Trigonometrie recht viel Zeit beansprucht.

    2. Kuenstliche Intelligenz ( Pfadsuche und Antizipationslawine )

    Der Flood-Fill ist ein Fuellalgorithmus, der den aktuell zu verarbeitenden
    Punkt markiert und als passiert markiert und sich selber mit dessen
    Nachbarpunkten aufruft, bis er an eine Umrandung oder Begrenzung trifft.
    Wenn man bei einem Flood-Fill ueber ein "Bitmap" mit Hindernissen
    die Funktionsaufrufe und deren Parameter in Datenstrukturen buffert und
    anhand eines Ausbreitungszaehlers die Ausfuehrungsreihenfolge der
    einzelnen Flood-Fill-Aufrufe ( etwa mit Bubblesort) umsortiert und
    den Flood-Fill beim erstmaligen Erreichen des Zieles abbricht und von
    dort den Weg der Aufrufe bis zum Start zurueckmarkiert, hat man den
    kuerzesten Pfad.
    Ob man den Flood-Fill in Baumstrukturen oder Arrays macht, steht einem
    frei. Aber beim Array muss man beachten, dass die Abstaende in schraegen
    Winkeln nicht der Anzahl Arraypunkte entsprechen, sondern sich mit dem
    Satz des Pythagoras errechnen. Man muá also das Array hochskalieren, h”her
    als die Auflösung des bei der Trigonometrie uebersprungenen Raums.
    Das fuehrt aber zu leichten Abweichungen und benötigt einen Haufen
    Rechenleistung.

    Mit Antizipationslawine ist gemeint, dass man einfach ausgehend vom konkreten
    naechsten Schritt saemtliche moeglichen Folgeschritte des Spielers
    einschliesslich der Gegner zum jeweiligen Zeitpunkt rekursiv durchrechnet
    und so entscheidet, ob bei der jeweils in Frage stehenden Aktion ein Vorteil
    oder ein Nachteil fuer den Computer entstehen kann.
    In einem einfachen Fall muss zunaechst entschieden werden, ob es sich aktuell
    um einen Spieler- oder Computerzug handelt. Handelt es sich um einen Com-
    puterzug, muessen alle Folgezuege des Spielers eine negative Bewertung
    haben. Handelt es sich um einen Spielerzug, reicht die unguenstige
    Bewertung eines einzigen Folgezugs des Spielers fuer eine schlechte
    Bewertung. Das ist der defensive Part. Beim Offensiven ist es genau
    umgekehrt. Eine bestimmte Routine simuliert dabei immer die in der
    Simulation gerade moegliche Folgeaktion und bewertet den vorausgesehenen
    Spielstatus. Diese Routine ruft sich selbst rekursiv mit ihrem eigenen
    simulierten Spielstatus auf und gibt bedingt durch die oben beschriebene
    logische Verknuepfung ihre Bewertung zurueck.
    Beim Ruecklauf aus der Rekursion wird der jeweils aktuelle letzte Zug wieder
    rueckgaengig gemacht.
    Bei einer bestimmten Vorausschautiefe ist wahrscheinlich Schluss und im
    Endeffekt zaehlt nur die Bewertung der Funktion an der Wurzel der
    Rekursion.
    Auch das benoetigt bereits bei einer geringen Vorausschautiefe einen
    Haufen Rechenleistung.

    3. Physik-Simulation
    Das ist die haerteste Nuss von Allem, aber gleichzeitig auch das Tollste,
    was es auf dieser Welt ueberhaupt gibt.
    Man unterteilt jedes Objekt in eine bestimmte Anzahl Einzelatome, die
    elastisch aneinander gebunden sind. Durch einen Summenterm von u.a.
    verschobenen und gestreckten Kehrbruch-Quadratfunktionen berechnet sich
    die Kraftwirkung jedes Fremdteilchens auf das jeweilige Eigenteilchen.
    Das heiát, man berechnet mit dem Satz des Pythagoras deren Distanz
    und "setzt diese" in den Funktionsterm fuer die Kraftwirkung "ein".
    Anschliessend verteilt man anhand der Steigung von x und y und z zueinander
    die errechnete Kraftwirkung auf x-, y- und z-Vektoraenderung, die
    zyklisch zu einer Koordinatenaenderung des Teilchens fuehrt.
    Es gibt auch den dreidimensionalen Satz des Pythagoras:
    Wurzel "x*x + y*y + z*z" . Das ist wegen Z.
    Wichtig ist, dass der Scheitelpunkt bzw. die Definitionsluecke der
    "Kehrbruch-Quadratfunktionen" nicht bei 0 liegen sollte, weil man
    hier erstens keinen Raum mehr fuer schraege Winkel haette und zweitens
    keine elastische Bindung zustandekaeme.
    Hinter dieser Distanz kippt die Ladung gerade ins Gegenteil.
    Das sind nicht die Kernbindungskräfte, sondern ansonsten wrde das
    Elektron ja ungebremst auf den Kern knallen?
    Es kann verschiedene Sorten Teilchen geben: Elektronen, Protonen, Neutronen,
    aber auch gravitationsfreie Teilchen (wie Elektronen), die nur eine
    elektrische Ladung haben. Das ist wegen der Massetraegheit bei der Gravitation.
    Elektrische Ladung entspricht wohl Masse.
    Man kann mehrere Sorten zusammenklumpen, indem man deren Abstaende entsprechend
    initialisiert.
    Man bedenke, dass bei einer Kollision im Grunde immer elektrische Ladungs-
    felder den Abprall bedingen. Das ist so laut Niels Bohr.
    Man simuliert also eine gewisse Anzahl aneinander gebundener Atome- man
    kann nie alle simulieren, aber die zu beobachtenden Effekte der Dynamik
    und Mechanik verhalten sich auch bei einer geringeren Anzahl Atome propor-
    tional und annaehernd gleich.
    Aus den Koordinaten bestimmter Atome errechnet man den Drehwinkel und
    die Position der korrespondierenden grafischen Darstellung im Raum.
    Der unelastische Stoß ist deshalb unelastisch, weil die Objekte aneinander
    kleben bleiben. Und das kommt, weil die Elektronen den Kern bis auf eine
    bestimmte Distanz anziehen.
    Verformung ist nur ein Nebeneffekt und nicht direkt Arbeit.
    Beim QT Elastic Nodes Example wird gezeigt, wie es geht. Dann macht man
    so ein Gitter in 3D und verbirgt es hinter einer entsprechend positionierten
    und gedrehten grafischen Darstellung etwa eines
    Rennautos oder Flugzeugs.
    Lassen die Sache mit dem Licht der Einfachheit halber weg. Ich kann darüber leider nur spekulieren. Irgendwie muß man es machen, wenn man ein Rennspiel schreiben will. Aber sich gleich auf Max Planck-, Einstein- oder Stephen Hawking-Niveau begeben... meine Vermutung: es gibt garkein Licht.

    Was ich mich wirklich frage: was waere, wenn man die Datensaetze fuer
    eine Physik-Simulation mit dem Computertomographen gewinnt?
    Ist das nicht krass, wenn das geht?!

    4. Fenstersystem
    Mit simplen Steuerbefehlen darstellen, vergleiche dazu, wie Grafikterminals
    funktionieren.
    Und fuer Sub-Widgets werden die Rahmenparameter der Elternfenstern(-teile)
    auf einem Stapelspeicher gestapelt und irgendwie mit den aktuellen
    Parametern vom Child-Objekt verrechnet.
    Shared-Memory, Systemaufrufe und Rumgepatche finden hier haeufig
    Anwendung, aber ein Fenstersystem ist nicht gleich ein komplettes
    Betriebssystem. Es geht auch einfacher mit einer kleinen Bibliothek im
    Hauptprogramm und einer "include"-Anweisung.

    5. Skriptcodeuebersetzer
    Es gibt fuer jeden Operator Eingrenzregeln, mit der man zwei Schiebezeiger
    auf bestimmte Tokens des Ausdrucks schiebt. Die Schieberegeln werden nach-
    einander in der Prioritaet absteigend angewandt und anschliessend erfolgt
    nach einer Reduktionsregel eine Ersetzung des begrenzten Teilausdrucks
    durch in der Regel eine Ergebnisvariable ("ein R-Wert") und die Ausgabe
    eines Assemblerfragments, in das als Platzhalter Variablen aus dem
    Teilausdruck eingefuegt
    werden koennen. Das wird solange wiederholt, bis der Ausdruck leergefegt
    ist oder aufgrund eines Syntaxfehlers nicht reduziert werden kann.

    Was sich kompliziert anhoert, ist im Wesentlichen das
    Gleiche wie "Punkt vor Strich und Klammern haben Vorfahrt".

    Beispiel:
    ( 7 + 5 ) * a ;

    1. Schiebe den rechten Eingrenz-Zeiger auf die erste geschlossene
    Klammer von links und den linken Zeiger auf die erste offene
    Klammer von dort.
    2. In dem eventuell eingegrenzten Bereich, schiebe die beiden Zeiger
    auf das erste Muster "Variabel * Variabel" oder "Variabel / Variabel"
    von links.
    3. In dem eventuell erneut eingegrenzten Bereich, schiebe die beiden
    Zeiger auf das erste Muster "Variabel + Variabel" oder "Variabel -
    Variabel" von links.

    Nun schau, auf welches Muster die beiden Zeiger zeigen, in dem Fall
    "7 + 5" und loesche nun das raus und ersetze es durch Ergebniswert_n,
    also im ersten Fall Ergebniswert_1 . Dann wuerde das Assemblerfragment

    "mov ax,7
    add ax,5
    mov [Ergebniswert_1],ax " ausgegeben werden.

    Das bedeutet im Klartext nichts anderes als
    Zaehle 7 und 5 zusammen
    Speichere das Ergebnis in Ergebniswert_1 .

    Der Prozessor kann nur die Grundrechenarten, den Befehlsspeicher im RAM
    abarbeiten und bedingt seine Register umladen und Werte aus dem RAM
    lesen oder schreiben. Assembler ist ganz einfach.

    ( 7 und 5 werden aus dem Ausdruck uebernommen und ins Assemblerfragment
    gefuegt. )

    4. Wiederhole alles von Vorne, reduziere auf aehnliche Weise die Klammern
    und die Multiplikation ( oder Division ) und breche mit der letzten Reduktion
    ab und mache weiter beim naechsten Ausdruck.

    Dann gibt es noch Bedingungen, also Ifs und Schleifen .
    Dafuer nimmt man einen Stapelspeicher, auf dem man Sprunglabels ablegt
    und bei Verlassen der Schachtelung in den Code einfuegt.
    Beispiel

    if ( 1 )
    wird uebersetzt zu

    Vergleiche Wert mit eins
    Springe ("goto, jnz") falls unwahr zu Marke "Marke_1",
    die sogleich auf dem Stapel landet.
    {

    if ( 0 )
    wird uebersetzt zu
    Vergleiche Wert mit eins
    Springe falls unwahr zu Marke "Marke_2",
    die sogleich auf dem Stapel landet.
    {

    } hole hier die oberste Sprungmarke vom Stapel und fuege sie an der
    entsprechenden Stelle im Assemblercode ein. Also

    Marke_2 :

    } hole hier die zweite (genauer: oberste) Sprungmarke vom Stabel und
    fuege sie in den Assemblercode ein, also

    Marke_1 :

    Dann gibt es auch noch Schleifen. Da kann bei der Uebersetzung
    auch das Count-Register involviert sein. Nur Switch Case ist ein
    wenig vertrackter. Man kann aber auch Steuersequenzen auf dem Stack
    unterbringen.
    Literaturtip: Drachenbuch, die Seite mit dem LR1-Algorithmus. Ist
    aber eher als Anregung zu verstehen, denn als Anleitung.

    Datentypdeklarationen werden wahrscheinlich auch mit einem Stapel und mit
    einem Eintrageverzeichnis aufgebaut. Also so Zeug wie verschachtelte Structs,
    was dann schon ins Pseudo-Komplexe ausarten kann.
    Fr die lexikalische Analyse Scanner mit Zustandsberg„ngen fr die akzeptierten
    Zeichen je Zustand.

    Ob ein Compiler zu Maschinencode oder zu Bytecode uebersetzt, steht jedem
    frei. Ein Bytecodeinterpreter ist nichts weiter als ein Programm, das anhand
    des Befehlssatzes einen Prozessor simuliert.
    So wie man einem Emulator ein Set Variablen fuer die Register des zu
    simulierenden Prozessors mit auf den Weg gibt, mit denen er dann den Speicher
    der zu emulierenden Maschine genauso manipuliert, wie deren Prozessor es tun
    wuerde.
    Die Schnittstelle zur Aussenwelt ist bei einer Emulation die emulierte
    Peripherie und bei einem Bytecodeinterpreter sind es einige Spezialroutinen
    oder Containervariablen.

    Man kann auch mit Codegeneratoren oder von Hand im Quellcode schaffen, aber
    viele Entwickler schreiben Bytecodeinterpreter, damit sie nicht dauernd
    im Hauptprogramm ( der "Engine") rumpfuschen muessen.

    6. Sound
    Eine Soundkarte ist eigentlich nur ein D/A-Wandler, an dem ein Lautsprecher
    haengt und an dem mit Taktung ( der "Samplerate" ) Werte ausgegeben werden.
    Die Anzahl der Richtungswechsel pro Zeit der so erzeugten Welle ist die
    Frequenz oder Tonhoehe und die Lautstaerke ist die Amplitude oder der
    Maximalausschlag.
    Mischen kann man Samples, indem man die Soundausgabe in einen Ausgabepuffer
    mit der Laenge grӇer der Laenge des laengstmoeglichen Samples schreibt
    und versetzt mit einem Offset ( relativ zur Ausgabeposition ) zusammenaddiert.
    Am Ende des Puffers faengt man gerade wieder an dessen Anfang an.
    Dann war da noch die Idee, nicht mit dieser komischen DCT, sondern mit der
    Physik-Simulation Resonanzschwingungen zu simulieren, indem man das Signal
    einem "virtuellen" Schwingkreis oder einer "virtuellen" Saite gegenrechnet
    und die Schwingstaerke abgreift. Wenn die DCT nicht hinhaut, kann man sowas
    in der Art auch fuer die Phonetik brauchen. Man braucht ja die
    "Frequenzdarstellung"

    7. Bilderkennung
    Die OCR gleicht Bitmaps mit einer Fuzzy-Logic ab und berechnet so den
    Grad der Uebereinstimmung. Das ist bekannt.
    Weniger bekannt ist aber, dass man eine Strichzeichnung erhaelt, wenn
    man ein Bild mit seinem unscharfen Negativ ueberlagert.
    Und dass diese Strichzeichnung eine prima Grundlage fuer den Abgleich
    anhand einer Fuzzy-Logic bietet.
    Und auf die Idee, das Vergleichsbitmap aus geometrischen Gleichungen
    mit variablen Parametern, die allesamt durchprobiert werden, einschliess-
    lich der Positionierung des Objekts im Raum und siehe Zentralprojektion
    zu generieren, muss man auch erstmal kommen.

    Es bleibt aber eine Heuristik.
    Daher auch die Idee, Schattenrisslinien zu berechnen.

    Auf Ähnlichkeit vergleichen: den Betrag der Pixeldifferenz aller korrespon-
    dierender Pixel beider Bilder aufsummieren und mit einem Schwellwert für
    ausreichende Übereinstimmung abgleichen.
    Verschiebevektoren, Drehungen und Skalierungen des Vergleichsbitmaps mit
    der Brechstange durchprobieren, dabei eventuell die Parameterbereiche
    eingrenzen, um Rechenleistung zu sparen. Man braucht für die meisten
    Fälle nur eine sehr geringe Auflösung. Für ein Gesicht könnten ca. 25x25
    Pixel reichen.
    Auch das MPEG könnte ähnliche Bereiche über einen Verschiebevektor einfach
    zusammenkopieren oder berblenden. Im Originalbitmap wird der entsprechende
    Bereich dann leer.

    Ich habe PC Underground von Data Becker im Regal stehen. Eine echte Rarität.


  • Mod

    Was ist der Zweck deiner Threads? Du hast offensichtlich viel Arbeit in sie gesteckt, aber ich kann nicht erkennen, dass du über irgendetwas reden möchtest.



  • Worum gehts?



  • Alter ego von prof84?
    nee, der TO kann deutsch.



  • Ist wohl eine Art Tagebucheintrag.



  • In der Besessenheit würde ich es als durchaus behandlungswürdig einstufen.



  • Riecht nach Scherfgen^^



  • Wir müssen ja nicht gleich so unfreundlich reagieren. Mir ist aber echt nicht klar, worums geht. Wer sind "sie" und was für "magisches Zeug" machen die?



  • "Sie" sind die Spieleentwickler und das magische Zeugs sind ... naja all die Dinge/Techniken die man halt verwendet um heute Spiele zu machen.



  • Finde ich alles ein wenig einfach gedacht. Zwischen den Grundlagen und einem guten Produkt liegt ein himmelweiter Unterschied. Aber klar: Ohne Grundlagen geht nichts. Sie sind die Grundsteine und öffnen Tür und Tor.



  • EOP schrieb:

    In der Besessenheit würde ich es als durchaus behandlungswürdig einstufen.

    Ich hab's geschrieben und es läuft garnicht mal soo langsam. Man lädt die Atomkkordinaten und die korrespondierenden Pixel aus der Eingabedatei.
    Behandlungsbedürftig wäre dann auch mein Netzhautschaden, weil mir aber auch nie irgendjemand irgendwas erklärt. Wenn ich mir die "Nogger"-Eisverpackung mit dem linken Auge anschaue, sehe ich wirklich den Schriftzug "N )gger".
    Wegen der Sonne vom 31.1.2007 .
    Und der Doktor Zachariou hat mir bei meinen Leistenbrüchen 1985 und 1986 zwei Lyoduras in die Bauchdecke genäht.
    Und Frau Hetzel-Kabiri hat mich ums Abitur beschissen. Und da sollte man doch mit aller Besessenheit dagegenwirken...

    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    float sqrtab[1000000];
    
    void sqrinit(void)
    {
     int count=0;
     while ( count < 1000000 )
     {
      sqrtab[count]=sqrt((float)count/1000.0 ) ;
      count++;
     }
    
    }
    
    float SQRT(float quad)
    {
      return ( sqrt(quad) );
     if ( quad < 0.0 ) quad*=-1.0 ;
    
     if (quad > 999 ) return ( sqrt(quad) );
    
     return sqrtab[ (unsigned int)( quad*1000.0) ];
    
    }
    
    float sintab[128];
    float costab[128];
    
    void sininit(void)
    {
     float value;
     value=-6.4;
    
     while ( value < 6.4 )
     {
      sintab[(int)((value+6.4)*10.0)]=sin(value);
      value+=0.1;
     }
    
    }
    
    void cosinit(void)
    {
     float value;
     value=-6.4;
    
     while ( value < 6.4 )
     {
      costab[(int)((value+6.4)*10.0)]=cos(value);
      value+=0.1;
     }
    
    }
    
    inline float SIN(float value)
    {
     signed int sign;
     signed int index;
    
     if ( value < 0 ) sign=-1;
     else sign=+1;
      index= ((int)( value*10 )%64);
      index+=63;
    
     return sintab[index];
    }
    
    inline float COS(float value)
    {
     signed int sign;
     signed int index;
    
     if ( value < 0 ) sign=-1;
     else sign=+1;
      index= ((int)( value*10 )%64);
      index+=63;
    
     return  costab[index];
    }
    
    struct
    {
     long unsigned x_next, y_next; /* korrekte Abstaende von Atom 2 und 3 zu Atom 1 */
     unsigned int num_atoms;
     long signed int atoms[64][9]; /* die ersten drei bestimmen den Winkel, zweites x, drittes y,
                                     die restlichen vier sind die Nachbarbindungsatome */
     unsigned int num_pixels;
     signed long pixgroup[8192][4]; /* Pixeldarstellung */
     float x_angl, y_angl, z_angl; /* Drehwinkel des Objekts */
     float x,y,z; /* Koordinaten. Ergeben sich aber dann aus den Atomkoordinaten. */
    }input_obj[32];
    
    float pixelbuf[131072][4];
    unsigned int pixelnum=0;
    unsigned int objnum=0;
    
    #define ZOOM 120.0 /* Skalierung der Zentralprojektion */
    #define VOXDEPTH 1
    
    int main(void)
    {
     FILE *input, *floor;
    
    struct
     {
      float x,y,z;
      float xv,yv,zv;
      int elec_or_prot;
    
      float distance;
      unsigned int objID;
      signed int bondNum1, bondNum2, bondNum3, bondNum4, bondNum5, bondNum6;
      float nearest;
     }teilchen[2048];
    unsigned int ATOMNUM=0;
    
     float power, old_power, x_buf, y_buf, z_buf, x_buf2, y_buf2, z_buf2, sign;
     float cmpadd_x, cmpadd_y;
     float x_cmp, y_cmp, z_cmp;
    
      signed int vox_x, vox_y, vox_z;
    
    struct
    {
     float x,y,z;
     float x_angl, y_angl, z_angl;
    
    } cam; /* die Projektionsflaeche und der Projektionspunkt */
    
    unsigned char floorLmap[512][512];
    unsigned char floorHmap[512][512];
    unsigned char screen[160][96];
    unsigned int zbuf[160][96]; /* vorderster Z-Wert eines projizierten Punkts pro Bildschirmkoordinate. */
    long int score=0;
    float game_ended=1000;
    
    unsigned char c;
    
    float speed=0.0, driveangl=0.0, xtomid, ztomid;
    
    signed long int counter=0;
    float distsample;
    long int old_pix_num;
    signed long int counter2=0;
    long unsigned int n,n2, n3;
    signed int screen_x, screen_y;
    int framereduce, framered2;
    
    float x_turned, y_turned, z_turned,
          x_turned2, y_turned2, z_turned2,
          x_turned3, y_turned3, z_turned3;
    
          sqrinit(), sininit(), cosinit();
    
    input=fopen(".\\3ddata.txt","rb");
    floor=fopen(".\\floor.map", "rb");
    if ( floor==NULL ) return;
    fread(floorHmap, sizeof(unsigned char), 512*512, floor);
    fread(floorLmap, sizeof(unsigned char), 512*512, floor);
    fclose(floor);
    
    vox_z=0;
    while ( vox_z < 512 )
    {
     vox_x=0;
     while ( vox_x < 512 )
     {
    
        c=floorLmap[vox_x][vox_z] ;
        if ( c < 64 ) c=' ';
        else
        if ( c < 128 ) c= 176;
        else
        if ( c < 196 ) c= 177;
        else
        if ( c < 255 )c= '@';
        floorLmap[vox_x][vox_z]=c;
    
      vox_x++;
     }
     vox_z++;
    }
    
    if ( input==NULL ) return;
    
       /* die Atomgruppen und die korrespondierenden Pixelgruppen mitsamt relativer
         Positionierung zueinander aus der Eingabedatei laden */
    
     while ( ! feof(input) )
     {
    
      fscanf(input,"%d %d", &input_obj[objnum].x_next,&input_obj[objnum].y_next );
      fscanf(input,"%d", &(input_obj[objnum].num_atoms) );
      counter=0;
      while ( counter < input_obj[objnum].num_atoms )
      {
       fscanf(input,"%d %d %d %d %d %d %d %d %d", &input_obj[objnum].atoms[(int)counter][0],
                                                  &input_obj[objnum].atoms[(int)counter][1],
                                                  &input_obj[objnum].atoms[(int)counter][2],
    
                                          &input_obj[objnum].atoms[(int)counter][3],
                                          &input_obj[objnum].atoms[(int)counter][4],
                                          &input_obj[objnum].atoms[(int)counter][5],
                                          &input_obj[objnum].atoms[(int)counter][6],
                                          &input_obj[objnum].atoms[(int)counter][7],
                                          &input_obj[objnum].atoms[(int)counter][8]  /* Bindungen */
                                            );
    
       counter++;
      }
    
      fscanf(input,"%d", &(input_obj[objnum].num_pixels) );
      counter=0;
      while ( counter < input_obj[objnum].num_pixels )
      {
       fscanf(input,"%d %d %d %d", &input_obj[objnum].pixgroup[(int)counter][0],
                                   &input_obj[objnum].pixgroup[(int)counter][1],
                                   &input_obj[objnum].pixgroup[(int)counter][2],
                                   &input_obj[objnum].pixgroup[(int)counter][3] );
    
       counter++;
      }
    
      objnum++;
    
     }
    fclose(input);
    objnum--;
    
    counter=0;
    counter2=0;
    ATOMNUM=0;
    
    while ( counter2 < objnum ) /* Atomgruppen in die Physiksimulation uebertragen */
    {
     counter=0;
     while ( counter < input_obj[counter2].num_atoms )
     {
      teilchen[ATOMNUM].x = input_obj[counter2].atoms[(int)counter][0];
      teilchen[ATOMNUM].y = input_obj[counter2].atoms[(int)counter][1];
      teilchen[ATOMNUM].z = input_obj[counter2].atoms[(int)counter][2];
      teilchen[ATOMNUM].bondNum1=input_obj[counter2].atoms[(int)counter][3];
      teilchen[ATOMNUM].bondNum2=input_obj[counter2].atoms[(int)counter][4];
      teilchen[ATOMNUM].bondNum3=input_obj[counter2].atoms[(int)counter][5];
      teilchen[ATOMNUM].bondNum4=input_obj[counter2].atoms[(int)counter][6];
      teilchen[ATOMNUM].bondNum5=input_obj[counter2].atoms[(int)counter][7];
      teilchen[ATOMNUM].bondNum6=input_obj[counter2].atoms[(int)counter][8];
    
      teilchen[ATOMNUM].elec_or_prot= (int)counter%1; /* mod */
      teilchen[ATOMNUM].objID = counter2;
    
      teilchen[ATOMNUM].xv=0;
      teilchen[ATOMNUM].yv=0;
      teilchen[ATOMNUM].zv=0;
    
      counter++;
      ATOMNUM++;
     }
     counter2++;
    }
    
    cam.x=0,cam.y=0, cam.z=0;
    cam.x_angl=0, cam.y_angl=0, cam.z_angl=0;
    
    while(1)
    {
    framered2=0;
    for(framereduce=0; framereduce < 10 ; framereduce++ )
    {
    
      /* Tastatureingaben entgegennehmen */
    
     if ( kbhit() )
     {
      c=getch();
      framered2=100;
    
     }
       else if ( framered2 == 0 ) c=0;
       framered2--;
    
       if(c=='u' ) cam.x-= -2*SIN(-cam.y_angl), cam.z-= -2*COS(-cam.y_angl);
       if(c=='j' ) cam.x+= -2*SIN(-cam.y_angl), cam.z+= -2*COS(-cam.y_angl);
       if(c=='h'  ) cam.y_angl+=0.04;
       if(c=='k' ) cam.y_angl-=0.04;
       if(c=='e') cam.y-=2;
       if(c=='d') cam.y+=2;
       if(c=='x') return;
       if ( c=='p' ) getch();
    
       if ( c=='v' ) if ( driveangl < 1.56 )driveangl+=0.04; /* eine Vektoraenderung koennte auch programmcodegesteuert erfolgen */
       if ( c=='n' ) if ( driveangl > - 1.56 ) driveangl-=0.04 ; /* z.B. zusaetzliche Angabe ueber Objekttyp */
       if ( c=='g' )  speed < 0.3 ? speed+=0.5 : (speed=0.3); /* vielleicht externer Bytecodeuebersetzer und Interpreter in diesem Programm */
       if ( c=='b' )  speed > -0.2 ? speed-=0.5 : (speed=-0.2);
    
         xtomid= -(teilchen[13].x - teilchen[4].x)*COS(-driveangl)
          -(teilchen[13].z - teilchen[4].z)*SIN(-driveangl);
    
          ztomid=  (teilchen[13].x - teilchen[4].x)*SIN(-driveangl)
          -(teilchen[13].z - teilchen[4].z)*COS(-driveangl);
    
         teilchen[4].xv+= xtomid*speed, teilchen[4].zv+=ztomid*speed;
    
         if ( speed > 0 ) speed-=0.005;
         else if ( speed < 0 ) speed+=0.005;
    
            if ( driveangl > 0.0 ) driveangl-=0.01;
            else if ( driveangl < 0.0 ) driveangl+=0.01;
    
        //  if ( fabs(speed) > 0.3 ) cam.x=teilchen[13].x - 30 , cam.z= teilchen[13].z + 120, cam.y_angl=driveangl+3.14, cam.y=14;
    
       /* Physik-Simulation. Je Eigenteilchen die Kraftwirkung aller umgebenden
         Fremdteilchen berechnen und auf die Vektoraenderung aufsummieren,
         danach bewegen. */
    
    #define PHYSLICE 11
    
    /* printf("Das X von Teilchen 0:%f Teilchen 1:%f",teilchen[0].x, teilchen[1].x); */
    
    n3=0;
    while( n3 < PHYSLICE )
    {
       if ( n3%1 == 0 )
       {
       n=0;
    
       n=0;
       while (n < ATOMNUM )
       {
    
        n2=0;
        while ( n2 < ATOMNUM )
        {
         if ( n==n2 ) { n2++; continue; }
         power=
        SQRT(
        ( teilchen[n].x - teilchen[n2].x)  *
        ( teilchen[n].x - teilchen[n2].x )+
           ( teilchen[n].y - teilchen[n2].y) *
        ( teilchen[n].y - teilchen[n2].y)+
         ( teilchen[n].z - teilchen[n2].z) *
        ( teilchen[n].z - teilchen[n2].z) ) ;
    
        old_power=power;
    
       x_buf=(teilchen[n].x - teilchen[n2].x);
       y_buf=(teilchen[n].y - teilchen[n2].y);
       z_buf=(teilchen[n].z - teilchen[n2].z);
    
      #define SCHEITEL 10.0  /* die Stelle der ladungsneutralen Luecke um den Kern */
      #define LADUNG   17.0      /* neu --> war 17.0 */
      #define LADNULL 1.0   // war vorher 0.5, sofortige Kraftabgabe
      #define TRAEGSCHWELLE 0.1 /* ist die Kraft schwaecher als das, findet keine Abgabe statt */
      #define ELANLOSS 0.0 /* beim unelastischen Stoss mogelt man eine Koordinatenaenderung rein */
      #define MAXKRAFT 2.5 /* so wird die aus der Distanz sich ergebende Kraft nie zu gross */
      #define PROT 1
      #define ELEK 0
    
      #define TIMESLICE 45.0
      #define VERLANGSFAC 0.98 /* allgemeiner Verlust Richtung 0, vielleicht wegen der Schwerkraft */
    
      if ( power-SCHEITEL < 0.0 ) sign= -1.0; else sign= 1.0;
       power=power-SCHEITEL;
    
        power= ( LADUNG / ((power *power )+MAXKRAFT) *sign  ) ;
    
        if ( fabs ( power) > LADNULL ) power=0; /*  Energiebegrenzung */
    
              if ( old_power != 0 )
              {
              y_buf*=power/old_power;
              x_buf*=power/old_power;
              z_buf*=power/old_power;
            } else x_buf=0, y_buf=0, z_buf=0;
    
        if ( (( teilchen[n].elec_or_prot==PROT
                && teilchen[n2].elec_or_prot==ELEK ) ||
              ( teilchen[n].elec_or_prot==ELEK
               && teilchen[n2].elec_or_prot==PROT )
               ||
    
                  (
               teilchen[n].objID==teilchen[n2].objID &&
               ( n2==teilchen[n].bondNum1 ||
                      n2==teilchen[n].bondNum2 ||
                      n2==teilchen[n].bondNum3 ||
                      n2==teilchen[n].bondNum4 ||
                      n2==teilchen[n].bondNum5 ||
                      n2==teilchen[n].bondNum6)
                   )
               )
    
          ) {  y_buf*=-1.0; x_buf*=-1.0; z_buf*=-1.0;
    
               if ( ( n2==teilchen[n].bondNum1 ||
                      n2==teilchen[n].bondNum2 ||
                      n2==teilchen[n].bondNum3 ||
                      n2==teilchen[n].bondNum4 ||
                      n2==teilchen[n].bondNum5 ||
                      n2==teilchen[n].bondNum6)
                    && teilchen[n].objID==teilchen[n2].objID )
               {
                #define KOHAERENZ 3
                x_buf*=KOHAERENZ,
                y_buf*=KOHAERENZ,
                z_buf*=KOHAERENZ;
                  }
    
               }
    
        if ( (old_power=SQRT ( x_buf*x_buf+y_buf*y_buf +z_buf*z_buf)) > TRAEGSCHWELLE )
       {
        /*
          power= (old_power-TRAEGSCHWELLE)/ old_power;
          x_buf*=power; y_buf*=power; z_buf*=power;  das war der Fehler*/
        }  else x_buf=0, y_buf=0, z_buf=0;
    
         if ( old_power > 0 && old_power > TRAEGSCHWELLE )
              {
               x_buf2+=(x_buf*ELANLOSS/TIMESLICE);
               y_buf2+=(y_buf*ELANLOSS/TIMESLICE);
               z_buf2+=(z_buf*ELANLOSS/TIMESLICE);
              }
    
       if ( teilchen[n].objID != teilchen[n2].objID )
        {
    
            #define POLARAUS 0.3
    
          //x_buf*=0.1, y_buf*=0.1, z_buf*=0.1;
          if ( x_buf > 0 && x_buf < POLARAUS) x_buf=0;
          else if ( x_buf >= POLARAUS ) x_buf-=POLARAUS ;
          else if ( x_buf < 0 && x_buf > -POLARAUS) x_buf=0;
          else if ( x_buf <= -POLARAUS )  x_buf+=POLARAUS ;
    
          if ( y_buf > 0 && y_buf < POLARAUS) y_buf=0;
          else if ( y_buf >= POLARAUS )  y_buf-=POLARAUS ;
          else if ( y_buf < 0 && y_buf > -POLARAUS) y_buf=0;
          else if ( y_buf <= -POLARAUS ) y_buf+=POLARAUS ;
    
          if ( z_buf > 0 && z_buf < POLARAUS) z_buf=0;
          else if ( z_buf >= POLARAUS )  z_buf-=POLARAUS ;
          else if ( z_buf < 0 && z_buf > -POLARAUS) z_buf=0;
          else if ( z_buf <= -POLARAUS )  z_buf+=POLARAUS ;
    
          } // war je 2 alt
    
        n2++;
    
        teilchen[n].xv+=x_buf;
        teilchen[n].yv+=y_buf;
        teilchen[n].zv+=z_buf;
    
        }
    
        n++;
       }
    
       n=0;
    
      n=0;
      while ( n < ATOMNUM )
      {
       if ( teilchen[n].x < 512 && teilchen[n].z < 512 && teilchen[n].x >=0 && teilchen[n].z >=0 )
        { if ( teilchen[n].y < 30+ floorHmap[(int)teilchen[n].x][(int)teilchen[n].z]*VOXDEPTH  /* && n3 == 0 */ ) teilchen[n].yv+=0.009; else /* if ( *//* ! (n3 > 0 ) */ /* teilchen[n].yv> 0) */ teilchen[n].yv-= (teilchen[n].y - 30+ floorHmap[(int)teilchen[n].x][(int)teilchen[n].z]*VOXDEPTH )/TIMESLICE; } // Schwerkraft
       else if ( teilchen[n].y < 30 /* && n3 == 0 */ ) teilchen[n].yv+=0.009; else /* if ( *//* ! (n3 > 0 ) */ /* teilchen[n].yv> 0) */ teilchen[n].yv-=(teilchen[n].y-30)/TIMESLICE; // Schwerkraft
    
        n++;
      }
        n=0;
    
      } // Aussetzer Ende
    
     if ( n3%1 == 0 )
     {
         while ( n < ATOMNUM )
      {
    
        teilchen[n].xv*=VERLANGSFAC; teilchen[n].yv*=VERLANGSFAC; teilchen[n].zv*=VERLANGSFAC;
    
       teilchen[n].x+=(teilchen[n].xv/TIMESLICE); teilchen[n].y+=(teilchen[n].yv/TIMESLICE) ;
        teilchen[n].z+=(teilchen[n].zv/TIMESLICE);
    
       n++;
      }
    
      }
    
      n3++;
     }
    
    } // Framereduce Ende
    
      counter=0;
      counter2=0;
     while ( counter2 < objnum )  /* Koordinaten des ersten Atoms zu Objektkoordinaten zuweisen */
     {
      input_obj[counter2].x=teilchen[(int)counter].x;
      input_obj[counter2].y=teilchen[(int)counter].y;
      input_obj[counter2].z=teilchen[(int)counter].z;
      teilchen[(int)counter].distance=0;
      teilchen[(int)counter].nearest=100000;
      counter++;
    
      while ( teilchen[(int)counter].objID == teilchen[(int)counter-1].objID ) counter++;
     counter2++;
     }
    
    counter2=0;
    counter=0;
    while ( counter < objnum )  /* aus den Koordinaten der bewegten Atome
                                   den naechsten korrespondierenden Drehwinkel der
                                   grafischen Darstellung ermitteln (Winkel durchprobieren) */
    {
    
       y_buf=-4.0;
       x_buf=-4.0;
       z_buf=-4.0;
    
      while ( x_buf < 4.0 )
      {
       y_buf=-4.0;
       while ( y_buf < 4.0 )
       {
        z_buf=-4.0;
        while ( z_buf < 4.0)
        {
         teilchen[counter2].distance=0;
         n=1;
    
    while ( n < 3 )
    {
    
            cmpadd_x=0, cmpadd_y=0;
    
           if ( n==1 ) cmpadd_x=input_obj[(int)counter].x_next;
           if ( n==2 ) cmpadd_y=input_obj[(int)counter].y_next;
    
        /* y-Achse */
    
           x_turned= +(cmpadd_x)*COS(y_buf)+(0)*SIN(y_buf);
           y_turned=cmpadd_y;
           z_turned= -(cmpadd_x)*SIN(y_buf)+(0)*COS(y_buf);
    
     /* x-Achse */
    
           y_turned2= +(y_turned)*COS(x_buf)-(z_turned)*SIN(x_buf);
           x_turned2=x_turned;
           z_turned2= (y_turned)*SIN(x_buf)+(z_turned)*COS(x_buf);
    
     /* z-Achse  */
    
           x_turned3= +(x_turned2)*COS(z_buf)-(y_turned2)*SIN(z_buf);
           z_turned3=z_turned2;
           y_turned3= (x_turned2)*SIN(z_buf)+(y_turned2)*COS(z_buf);
    
           x_cmp=x_turned3+teilchen[counter2].x,
           y_cmp=y_turned3+teilchen[counter2].y,
           z_cmp=z_turned3+teilchen[counter2].z;
    
           x_cmp= fabs(x_cmp-teilchen[counter2+n].x);
           y_cmp= fabs(y_cmp-teilchen[counter2+n].y);
           z_cmp= fabs(z_cmp-teilchen[counter2+n].z);
    
           teilchen[counter2].distance+= (x_cmp+y_cmp+z_cmp);
    
           n++;
    }
    
           if ( teilchen[counter2].distance < teilchen[counter2].nearest )
          {
            input_obj[(int)counter].x_angl=x_buf,
            input_obj[(int)counter].y_angl=y_buf,
            input_obj[(int)counter].z_angl=z_buf;
    
            teilchen[counter2].nearest=teilchen[counter2].distance;
    
           }
    
         z_buf+=0.2;
        }
    
        y_buf+=0.2;
       }
       x_buf+=0.2;
      }
    
      while ( teilchen[counter2].objID == teilchen[counter2+1].objID && counter2 < ATOMNUM-1) counter2++;
    
      /*printf("X-Wink: %f Y-Wink: %f Z-Wink: %f\n",input_obj[counter].x_angl, input_obj[counter].y_angl,
                                  input_obj[counter].z_angl ); *//* debug */
    
      counter2++;
     counter++;
    
    }
    
    /* printf("X-Wink: %f Y-Wink: %f Z-Wink: %f  %d\n",input_obj[1].x_angl, input_obj[1].y_angl,
                                  input_obj[1].z_angl, counter2 ); */ /* debug */
    
       /* Bildschirm leeren, Z-Buffer initialisieren */
         screen_y=0;
      while(screen_y<96)
      {
       screen_x=0;
       while(screen_x<160)
       {
        screen[screen_x][screen_y]=219;
        zbuf[screen_x][screen_y]=100000;
        screen_x++;
       }
       screen_y++;
       }
    
    #define BUFX 0
    #define BUFY 1
    #define BUFZ 2
    #define VALUE 3
    
     pixelnum=0;
    
    counter2=0;
    
    while( counter2 < objnum ) /* fuer jeden einzelnen Pixel dessen Drehungen
                                 anhand der Objektpositionierung berechnen */
    {
     counter=0;
      while(counter < input_obj[counter2].num_pixels && counter < input_obj[counter2].num_pixels)
      {
       if ( input_obj[counter2].pixgroup[counter][VALUE] != 0 )
       {
        pixelbuf[pixelnum][BUFX]=input_obj[counter2].pixgroup[counter][BUFX]  +input_obj[counter2].x ;
        pixelbuf[pixelnum][BUFY]=input_obj[counter2].pixgroup[counter][BUFY] +input_obj[counter2].y ;
        pixelbuf[pixelnum][BUFZ]=input_obj[counter2].pixgroup[counter][BUFZ] +input_obj[counter2].z ;
        pixelbuf[pixelnum][VALUE]=(unsigned char)input_obj[counter2].pixgroup[counter][VALUE];
    
    /* y-Achse */
    
           x_turned= +(pixelbuf[pixelnum][BUFX]-input_obj[counter2].x)*COS(input_obj[counter2].y_angl)+(pixelbuf[pixelnum][BUFZ]-input_obj[counter2].z)*SIN(input_obj[counter2].y_angl);
           y_turned=pixelbuf[pixelnum][BUFY]    -input_obj[counter2].y; /* Subtraktion eingefuegt */
           z_turned= -(pixelbuf[pixelnum][BUFX]-input_obj[counter2].x)*SIN(input_obj[counter2].y_angl)+(pixelbuf[pixelnum][BUFZ]-input_obj[counter2].z)*COS(input_obj[counter2].y_angl);
    
     /* x-Achse */
    
           z_turned2= (y_turned)*SIN(input_obj[counter2].x_angl)+(z_turned)*COS(input_obj[counter2].x_angl);
           y_turned2= (y_turned)*COS(input_obj[counter2].x_angl)-(z_turned)*SIN(input_obj[counter2].x_angl);
           x_turned2=x_turned;
    
     /* z-Achse  */
    
           y_turned3= (x_turned2)*SIN(input_obj[counter2].z_angl)+(y_turned2)*COS(input_obj[counter2].z_angl);
           x_turned3= (x_turned2)*COS(input_obj[counter2].z_angl)-(y_turned2)*SIN(input_obj[counter2].z_angl);
           z_turned3= z_turned2;
    
          pixelbuf[pixelnum][BUFX]=x_turned3+input_obj[counter2].x;
          pixelbuf[pixelnum][BUFY]=y_turned3+input_obj[counter2].y;
          pixelbuf[pixelnum][BUFZ]=z_turned3+input_obj[counter2].z;
    
         pixelnum++;
        }
         if ( pixelbuf[pixelnum-1][BUFZ]-cam.z > ZOOM*4 )    counter+=2;
        else counter++;
                        /* unterschiedliche Pixelzahlen nach Abstand */
    
      }
      counter2++;
    
    }
    
     counter=0;
    
     old_pix_num=pixelnum;
     distsample=0.0;
     while ( counter < old_pix_num ) /* Projektion aller Pixel zur Kamera, vorher: Kameradrehung berechnen */
     {
    
    /* y-Achse */
    
           x_turned= +(pixelbuf[(int)counter][BUFX]-cam.x)*COS(cam.y_angl)+(pixelbuf[(int)counter][BUFZ]-cam.z)*SIN(cam.y_angl);
           y_turned=pixelbuf[(int)counter][BUFY];
           z_turned= -(pixelbuf[(int)counter][BUFX]-cam.x)*SIN(cam.y_angl)+(pixelbuf[(int)counter][BUFZ]-cam.z)*COS(cam.y_angl);
    
             pixelbuf[(int)counter][BUFX]=x_turned+cam.x;
            pixelbuf[(int)counter][BUFY]=y_turned;
            pixelbuf[(int)counter][BUFZ]=z_turned+cam.z;
    
            if ( z_turned < ZOOM )
            {
    
            #define DOUBLEFILL(xoff,yoff) \
             pixelbuf[(int)pixelnum][BUFX]=x_turned+xoff+cam.x; \
            pixelbuf[(int)pixelnum][BUFY]=y_turned+yoff;\
            pixelbuf[(int)pixelnum][BUFZ]=z_turned+cam.z;\
            pixelbuf[(int)pixelnum][VALUE]=pixelbuf[(int)counter][VALUE];\
    \
             pixelnum++;\
    
             DOUBLEFILL (-1*z_turned/ZOOM,-1*z_turned/ZOOM)
             DOUBLEFILL (1*z_turned/ZOOM,-1*z_turned/ZOOM)
             DOUBLEFILL (0,-1*z_turned/ZOOM)
             DOUBLEFILL (-1*z_turned/ZOOM,0)
             DOUBLEFILL (1*z_turned/ZOOM,0 )
             DOUBLEFILL (-1*z_turned/ZOOM,1*z_turned/ZOOM)
             DOUBLEFILL (0,1*z_turned/ZOOM)
             DOUBLEFILL (1*z_turned/ZOOM,1*z_turned/ZOOM)
    
            }
    
      counter++;
     }
    
     // Hoehenkarte
    
     vox_z=0;
     while ( vox_z < 512 )
     {
      vox_x=0;
    
      while ( vox_x < 512 )
      {
           x_turned= +(vox_x-cam.x)*COS(cam.y_angl)+(vox_z-cam.z)*SIN(cam.y_angl);
           y_turned=floorHmap[vox_x][vox_z];
           z_turned= -(vox_x-cam.x)*SIN(cam.y_angl)+(vox_z-cam.z)*COS(cam.y_angl);
    
           x_turned+=cam.x;
           z_turned+=cam.z;
    
        #define SETVOXEL(xf,yf,zf) \
      if ( (z_turned-(float)cam.z)/ZOOM>0  ) \
          { \
           if( (79.0 + ( (signed int)xf -cam.x)/(((signed int)zf-cam.z)/ZOOM)) < 160 && 47.0 + ((yf-cam.y)/(((signed int)zf-cam.z)/ZOOM)) < 90.0 && \
               79.0 + (( (signed int)xf -cam.x)/(((signed int)zf-cam.z)/ZOOM)) >= 0 && 47.0 + ((yf-cam.y)/(((signed int)zf-cam.z)/ZOOM)) >= 0   ) \
           if ( zbuf[ (signed int) (79.0 + (( (signed int)xf -cam.x)/(((signed int)zf-(float)cam.z)/ZOOM))) ] [ (signed int)(47.0 + ((yf-cam.y)/(((signed int)zf-cam.z)/ZOOM))) ] > ((signed int)zf-cam.z) ) \
                zbuf[ (signed int) (79.0 + \
                (( (signed int)xf -cam.x))/ \
                (((signed int)zf-(float)cam.z)/ZOOM)) ] \
                [ (signed int)(47.0 + ((yf-cam.y)/(((signed int)zf-(float)cam.z)/ZOOM))) ] \
                =((signed int)zf-cam.z), \
           screen[ (signed int) (79.0 + (( (signed int)xf -cam.x)/(((signed int)zf-(float)cam.z)/ZOOM))) ] [ (signed int)(47.0 + (((signed int)yf-cam.y)/(((signed int)zf-cam.z)/ZOOM))) ]=(unsigned char)floorLmap[vox_x][vox_z]; }\
    
        SETVOXEL(  ((signed int)x_turned-1),(30+y_turned), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned),(30+y_turned), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned+1),(30+y_turned-1), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned-1),(30+y_turned-1), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned),(30+y_turned-1), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned+1),(30+y_turned), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned-1),(30+y_turned+1), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned),(30+y_turned+1), ((signed int)z_turned ))
        SETVOXEL(  ((signed int)x_turned+1),(30+y_turned+1), ((signed int)z_turned ))
    
       vox_x++;
       if ( z_turned > ZOOM ) vox_x++;
       if ( z_turned > ZOOM*3 ) vox_x++;
       if ( z_turned > ZOOM*6 ) vox_x+=2;
    
      }
    
      if ( z_turned > ZOOM ) vox_z++;
       if ( z_turned > ZOOM*3 ) vox_z++;
       if ( z_turned > ZOOM*6 ) vox_z+=2;
    
      vox_z++;
     }
    
     while ( pixelnum > 0 )
     {
      pixelnum--;
    
       /* die eigentliche Projektion */
    
      if ( (pixelbuf[pixelnum][BUFZ]-(float)cam.z)/ZOOM>0  )
          {
           if( (79.0 + (pixelbuf[pixelnum][BUFX]-cam.x)/((pixelbuf[pixelnum][BUFZ]-cam.z)/ZOOM)) < 160 && 47.0 + ((pixelbuf[pixelnum][BUFY]-cam.y)/((pixelbuf[pixelnum][BUFZ]-cam.z)/ZOOM)) < 90.0 &&
               79.0 + ((pixelbuf[pixelnum][BUFX]-cam.x)/((pixelbuf[pixelnum][BUFZ]-cam.z)/ZOOM)) >= 0 && 47.0 + ((pixelbuf[pixelnum][BUFY]-cam.y)/((pixelbuf[pixelnum][BUFZ]-cam.z)/ZOOM)) >= 0   )
           if ( zbuf[ (signed int) (79.0 + ((pixelbuf[pixelnum][BUFX]-cam.x)/((pixelbuf[pixelnum][BUFZ]-(float)cam.z)/ZOOM))) ] [ (signed int)(47.0 + ((pixelbuf[pixelnum][BUFY]-cam.y)/((pixelbuf[pixelnum][BUFZ]-cam.z)/ZOOM))) ] > (pixelbuf[pixelnum][BUFZ]-cam.z) )
                zbuf[ (signed int) (79.0 +
                ((pixelbuf[pixelnum][BUFX]-cam.x))/
                ((pixelbuf[pixelnum][BUFZ]-(float)cam.z)/ZOOM)) ]
                [ (signed int)(47.0 + ((pixelbuf[pixelnum][BUFY]-cam.y)/((pixelbuf[pixelnum][BUFZ]-(float)cam.z)/ZOOM))) ]
                =(pixelbuf[pixelnum][BUFZ]-cam.z),
           screen[ (signed int) (79.0 + ((pixelbuf[pixelnum][BUFX]-cam.x)/((pixelbuf[pixelnum][BUFZ]-(float)cam.z)/ZOOM))) ] [ (signed int)(47.0 + ((pixelbuf[pixelnum][BUFY]-cam.y)/((pixelbuf[pixelnum][BUFZ]-cam.z)/ZOOM))) ]=pixelbuf[pixelnum][VALUE];
        }
    
     }
    
       /* Uebertragen des Screenbuffers auf den Bildschirm ( hier: Textmodus,
         zukuenftig: Grafikmodus ). */
      system("cls\n");
    
       /* Teilchendump debug */
    
       /*
      screen[(int)teilchen[0].x+80][(int)teilchen[0].y+20]='1';
      screen[(int)teilchen[1].x+80][(int)teilchen[1].y+20]='2';
      screen[(int)teilchen[2].x+80][(int)teilchen[2].y+20]='3';
      screen[(int)teilchen[3].x+80][(int)teilchen[3].y+20]='4';
      screen[(int)teilchen[4].x+80][(int)teilchen[4].y+20]='5';
      screen[(int)teilchen[5].x+80][(int)teilchen[5].y+20]='6';
      screen[(int)teilchen[6].x+80][(int)teilchen[6].y+20]='7'; */
    
      screen[79][47]='X'; /* debug */
    
      screen_y=0;
    
      while(screen_y<70)
      {
       screen_x=0;
       while(screen_x<160)
       {
        printf("%c%c%c%c%c%c%c%c",screen[screen_x][screen_y],
                                  screen[screen_x+1][screen_y],
                                  screen[screen_x+2][screen_y],
                                  screen[screen_x+3][screen_y],
                                  screen[screen_x+4][screen_y],
                                  screen[screen_x+5][screen_y],
                                  screen[screen_x+6][screen_y],
                                  screen[screen_x+7][screen_y]);
        screen_x+=8;
       }
        printf("\n");
       screen_y++;
       }
        /*
        printf("%f %f %f\n"
               "%f %f %f\n"
               "%f %f %f\n",teilchen[0].x, teilchen[0].y, teilchen[0].z,
                            teilchen[4].x, teilchen[4].y, teilchen[4].z,  // war 4,5
                            teilchen[5].x, teilchen[5].y, teilchen[5].z );          */
        if ( score < 1000 && game_ended >= 5 )
        printf("%d %f\n", 1000-score, game_ended=SQRT( (256-teilchen[27].x)*(256-teilchen[27].x)+
                                       (256-teilchen[27].z)*(256-teilchen[27].z)+
                                       (32-teilchen[27].y)*(32-teilchen[27].y)) ),
         (game_ended > 5 ? score++ : 0);
         else { if ( game_ended > 5 ) printf("Game Over!"); else printf("%f Punkte",1000-score); };
    
      /*  printf("%f %f %d\n",cam.x,cam.y,pixelbuf[12][VALUE] ); */ /*debug*/
    }
    
    /* Klar macht es erstmal einen Scheisseindruck.
      Aber ich irre mich nicht in der Annahme, dass der Grundstein gelegt ist und dass
      hier ein enormes Potential drinsteckt.
      Es ist der Grundstock fuer eine 3D-Engine und eine Physik-Simulation.
      Mit den richtigen Parametern kann das eindrucksvoll und toll werden. */
    
     }
    


  • das war die Originalgrafik von Doom.
    Da gab es 1993/1994 Riesendiskussionen drüber, weil nämlich die mit der Zentralprojektion projizierten Sprites zu real wirkten.
    Und dann machte die BPJM, die damals noch BPJS hieß, eine Studie über schädigende Medienwirkungen. Dazu wurden über die staatlichen Lizenzen ein Haufen Scheißinhalte unters Volk gestreut.
    Lest ihr zum Beispiel "AMERICAN BLEND" und streicht das italienische "CREMA" für Sonnencreme raus, erhaltet ihr ein Anagramm für "Bin Laden".
    Aber es ging beim Rauchen wohl garnicht um Krebs, sondern um den Mediendachschaden, der durch den medialen Verzehr von Krebs-Melodramen entsteht.
    Und Lyodura ist eine Zombiescheiße. Wenn ihr euch "Zombie im Kaufhaus" angeschaut habt, wo Peter gebissen wird und langsam innerhalb von drei Tagen verblödet, ist psychoanalytisch die Wirkung, daß ihr hinterher meint, an einer Gehirnzehrung zu meiden.
    "BRAUN MELSUNGEN".
    Vom Melanin wird man in der Sonne genetisch bevorzugt braun.
    Und "SANG" auf lateinisch oder französisch bedeutet "Blut".
    Und meint ihr, bei einer Verbrennung wird eure Haut nicht anfangen zu bluten?
    Beim Jugendschutz geht es um Medienwirkungen. Und sowohl Siechtum als auch Gewalt (Hitler, Rassismus), gelten als hochgradig jugendgefährdend.
    Und sie kennen die Wirkungen differenzierter, als ihr meint.
    Das ist meine Idee. Aber ich selber schiebe schon jetzt wieder Panik, weil ich aufpassen muß, was ich sage. Ich baue nach...
    Blond und Blood und Blind.
    Erstes französisches Opfer in Lyon.
    Osama bedeutet Löwe.
    Brown und Brain -- "Rainbow".


  • Mod

    Ich wiederhole noch einmal die Frage: Willst du hier irgendetwas diskutieren oder hast du das Forum mit deinem persönlichem Blog verwechselt?



  • SeppJ schrieb:

    oder hast du das Forum mit deinem persönlichem Blog verwechselt?

    Das. Wobei ich es nicht so höflich formuliert hätte 😃


  • Mod

    hustbaer schrieb:

    SeppJ schrieb:

    oder hast du das Forum mit deinem persönlichem Blog verwechselt?

    Das. Wobei ich es nicht so höflich formuliert hätte 😃

    Ich wollte eigentlich noch einen schnippischen Kommentar abgeben, warum wohl niemand sein Blog liest, habe es mir aber in letzter Sekunde verkniffen. Da ich nun gesagt habe, dass ich dazu etwas zu sagen gehabt hätte, kann er sich nun natürlich denken, was ich wohl zu sagen gehabt hätte 😃



  • kommt mir vor wie ein typ von hier

    http://mahag.com/neufor/index.php?sid=5ec9b26512b994bcf47f87fc4dafc7ce

    da geht es im prinzip nicht um das finden von lösungen bzw. der wahrheit sondern nur um labern, geistiges ejakulieren und andere zu diskussionen zu provozieren um das eigene ego zu stärken/zu befüttern.

    arm.



  • Immerhin hat dieser Thread schon 800+ Hits und damit wohl mehr Aufmerksamkeit als ein Blog zu diesem Thema.



  • Als hätte ich nicht schon von Anfang an gemerkt, dass da ein behandlungswürdiger Fall vorliegt...



  • tenim schrieb:

    kommt mir vor wie ein typ von hier

    http://mahag.com/neufor/index.php?sid=5ec9b26512b994bcf47f87fc4dafc7ce

    da geht es im prinzip nicht um das finden von lösungen bzw. der wahrheit sondern nur um labern, geistiges ejakulieren und andere zu diskussionen zu provozieren um das eigene ego zu stärken/zu befüttern.

    arm.

    Naja, wenn man die richtigen Datensätze reinlädt, stellt es wirklich die Pixeldarstellung von zwei Autos auf einer Straße mit einem Tal dar.
    Und wenn man dann einen Würfel aus 3x3x3 Einzelteilchen der grafischen Darstellung
    zuordnet, kann man Kräfte auf den Würfel wirken lassen, den dreht und verschiebt es dann und er hebt trotzdem zusammen und die Positionierung und die Drehung der grafischen Darstellung passt es dann entsprechend an, das Auto bewegt sich dann sozusagen mit.
    Man muß die Auflösung des Konsolenfensters umstellen und dann stellt es mit vier bstimmten ASCII-Werten vier Graustufen mit einer Auflösung von 160x70(?) dar.
    Wenn man die Physik richtig anpasst, könnte es hinkommen.
    Ich will keine Diskussionen provozieren, ich habe wirklich keinen Durchblick mehr. Und möchte man nur die Dynamik simulieren, landet man gleich bei der blöden Atombombe.



  • das ist jetzt auf keinen fall böse gemeint, aber du solltest wirklich erwägen, in psychiatrische behandlung zu gehen.


Anmelden zum Antworten