Kleines Side-Projekt, das ich mal einigermaßen fertig gemacht habe.
Ursprungsgedanke war, Polygone per Maus in 2D bearbeiten zu können. Dann irgendwie tesselieren, und einfache World-Y-Extrusion per Parameter dazu (Bodenhöhe, Blockhöhe), und schon kann man einfache 3D-Umgebungen für Prototyping basteln. Ein bischen wie Doom1-Levelgeometrie, mehr oder weniger.
Beim "irgendwie tesselieren" kam ich zwischenzeitlich darauf, dass es ja sowieso sehr einfache Polys bleiben, und es wohl reichen dürfte, den Startpunkt für einen Fan manuell festlegen zu können.
Dadurch kann man, wie im Bild zu sehen, einfache konkave Polygone ohne viel Tamtam dahinter tesselieren. Ich rendere die Polys transparent und mit Dreieckslinien bei selektiertem Polygon, d.h. man sieht sofort wo was nicht passt und kann andere Startpunkte ausprobieren.
Beispielszenen, im Download mit dabei:
Bedienung:
In 3D kann man nur betrachten. Kein Dolly, sondern WASD2X + Maus.
Im 2D-Canvas:
- MMB + Mousewheel: Pan und Zoom.
- Linien/Punkte/Polygone anfassen, verschieben, löschen. Wenn man ein kleines Poly verschieben möchte, aber erwischt immer nur Punkte oder Linien: ranzoomen.
- STRG+Klick für neue Punkte. Wenn ein Poly markiert ist, wird dort ein neuer Punkt eingefügt. Ansonsten ein neues Poly begonnen. Polyorder wird automatisch korrigiert, da muss man nichts beachten.
- Wenn man mal an ein Poly nicht mehr ran kommt: das darüberliegende markieren und "send to back".
- Selektiertes Polygon: ALT+verschieben=Duplizieren; R=Rotate (90°), M=Mirror.
- Doppelklick auf einen Punkt: von diesem aus neu tesselieren.
Man kann nur im Raster und Ganzzahlen arbeiten.
Höhe wird vom letzten markierten Block beibehalten, Boden wird je nach Mausposition beim Erstellen ermittelt, aber nicht beim Verschieben geändert.
Was NICHT geht:
Undo, zerschneiden, frei drehen, Rampen bauen, gruppieren, Multiselektion, texturieren, einfärben, Warnungen wenn man nicht gespeichert hat bei clear/load/quit, usw.
Es ist halt wirklich nur für schnelle kleine Protoszenen gedacht, wenn man mal schnell was bauen, aber keinen ausgewachsenen 3D-Editor bedienen möchte. Daher habe ich manche Features, welche die Bedienung komplexer machen würden, erstmal weggelassen. Aber ein paar Sachen kommen sicher mit der Zeit dazu.
Exportformate:
- Das native Format ist binär. Doku lohnt sichjetzt nicht, weil:
- txt ist im Prinzip dasselbe, nur lesbar und selbsterklärend. Für eigene Anwendungen.
- tris ist nur Geometrie als rohe Dreiecksliste, unique Vertices, keine Indices.
- obj ist ebenfalls im Textformart, mit indizierten Vertices, zum Weiterarbeiten in 3D-Software. Ob konkave Polygone richtig tesseliert werden, hängt dann vom Programm ab. In Blender hatten erste Versuche geklappt, in Cura ebenfalls.
Ich möchte nicht ausschließen, dass ich bei dem ein oder anderen Export noch einen Fehler drin habe, ist alles nicht auf Herz und Nieren geprüft.
Es gibt ein paar experimentelle Features, z.B. wenn man bei type "trigger" oder "path" eintippt, werden diese anders dargstellt. Ist mal gedacht als kleiner Levelbuilder, wo man dann die Polyblöcke als einfache Collider weiterbenutzen, aber am Ende andere Geometrie hinterlegen kann.
Ich dachte ich werfs einfach mal im aktuellen Zustand in die Runde:
[Projekt] Polyblock-Editor
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.
Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.
This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.
Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.
This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
-
- Establishment
- Beiträge: 210
- Registriert: 25.08.2019, 05:00
- Alter Benutzername: gdsWizard
- Kontaktdaten:
Re: [Projekt] Polyblock-Editor
Ich finde das sieht schon ziemlich gut aus. Ein brauchbarer Editor, auch wenn noch ein paar Features, wie sie selber bemerkten, noch fehlen. Ich hoffe ich kriege mit meinem Editor auch mal sowas hin.
ehemals gdsWizard, http://www.mirrorcad.com
Re: [Projekt] Polyblock-Editor
thx :)
Kleiner Bug: Wenn man gerade eine Line oder Punkt selektiert hatte, dann auf den Hintergrund klickt (ohne STRG) um die Auswahl aufzuheben, dann ein neues Poly mit STRG beginnen möchte, geht das nicht. Abhilfe: Ein ganzes Poly selektieren, dann aufden Hintergrund klicken.
State-Hölle, es gibt bei sowas mehr Zustände auf die man unterschiedlich reagieren muss als man dem Ganzen ansieht.
Kleiner Bug: Wenn man gerade eine Line oder Punkt selektiert hatte, dann auf den Hintergrund klickt (ohne STRG) um die Auswahl aufzuheben, dann ein neues Poly mit STRG beginnen möchte, geht das nicht. Abhilfe: Ein ganzes Poly selektieren, dann aufden Hintergrund klicken.
State-Hölle, es gibt bei sowas mehr Zustände auf die man unterschiedlich reagieren muss als man dem Ganzen ansieht.
Re: [Projekt] Polyblock-Editor
Ich werfe auch noch ein paar (Pseudo)Codesnippets und weitere Infos in die Runde, die hilfreich sein könnten wenn man das für eigene Projekte ausprobieren möchte.
Datentyp für einen Block:
Textformat im Vergleich dazu:
Das native Binärformat ist nicht wesentlich anders, allerdings Float-basiert. Außerdem: Die vec2 werden als 4 floats x,y,0,1 geschrieben, aber nur die ersten beiden Komponenten sind in dieser Version relevant. (WriteVec() == 4x writeFloat())
Triangulate, zum Rendern.
Ist extruded auf false, wird nur das Polygon zurückgegeben. Ansonsten der Block mit Seitenwänden, Boden und Deckel.
X,Y wird zu X,-Z, da bei mir +X=rechts, +Y=oben, +Z=vorn in 3D.
Demnächst kommen noch Snippets zu:
- 2D-Picking (point inside poly?)
- 3D-Kollisionserkennung (Kugel vs. Block)
- Response (Kontaktnormale)
Datentyp für einen Block:
Code: Alles auswählen
class PolyBlock
public string name = "";
public string type = "";
public float bottom = 0;
public float height = 1;
public List<Vector2> verts = new List<Vector2>();
Code: Alles auswählen
//POLYBLOCK SCENE
numBlocks 2
//POLYBLOCK
name
type
bottom 000
height 003
numVerts 9
010 020 009 026 001 026 -004 020
-004 012 008 007 017 008 018 012
024 020
//POLYBLOCK
name bla
type blub
bottom 000
height 007
numVerts 7
-001 007 -015 024 -009 010 -017 -011
-001 001 011 -007 018 003
//EOF
Code: Alles auswählen
stream.writeString(name);
stream.writeString(type);
stream.writeFloat(bottom);
stream.writeFloat(height);
stream.writeInt(verts.Count);
foreach (var vert in verts) stream.writeVec(new Vector4(vert.X, vert.Y, 0, 1));
Ist extruded auf false, wird nur das Polygon zurückgegeben. Ansonsten der Block mit Seitenwänden, Boden und Deckel.
X,Y wird zu X,-Z, da bei mir +X=rechts, +Y=oben, +Z=vorn in 3D.
Code: Alles auswählen
public List<Vector3> triangulate(bool extruded)
{
List<Vector3> tris = new List<Vector3>();
int n = verts.Count;
float bt = extruded ? bottom : 0;
Vector3 v0 = new Vector3(verts[0].X, bt, -verts[0].Y);
Vector3 vh = new Vector3(0, extruded?height:0, 0);
//surfaces
for (int i = 2; i < n; i++)
{
Vector3 v1 = new Vector3(verts[i - 1].X, bt, -verts[i - 1].Y);
Vector3 v2 = new Vector3(verts[i].X, bt, -verts[i].Y);
//bottom
if (extruded)
{
tris.Add(v0);
tris.Add(v2);
tris.Add(v1);
}
//top
tris.Add(v0 + vh);
tris.Add(v1 + vh);
tris.Add(v2 + vh);
}
//sides
if (extruded)
{
for (int i = 0; i < n; i++)
{
Vector3 v1 = new Vector3(verts[i].X, bt, -verts[i].Y);
Vector3 v2 = new Vector3(verts[(i + 1) % n].X, bt, -verts[(i + 1) % n].Y);
tris.Add(v1);
tris.Add(v2);
tris.Add(v2 + vh);
tris.Add(v2 + vh);
tris.Add(v1 + vh);
tris.Add(v1);
}
}
return tris;
}
- 2D-Picking (point inside poly?)
- 3D-Kollisionserkennung (Kugel vs. Block)
- Response (Kontaktnormale)