Ankündigung

Einklappen
Keine Ankündigung bisher.

Random Punkt auf own.meshes finden?

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Random Punkt auf own.meshes finden?

    Ich würde gern wissen ob man von einem Mesh-Objekt, z.b. mit nur einem einzelnen Face, einen random Punkt, der auf diesem Face liegt, finden kann.

    Also ungefähr so im Script:
    import random
    Vektor = random.choice(PunktaufdeinemMesh)

    (nur zum Verständnis, bitte nicht ernst nehmen)

    Hilfreich wäre vielleicht eine Liste der Polygone + Vertices, falls jemand weiß wie man da rankommt.

    Verwenden will ich das Ganze dann um Landschaftsobjekte random zu setzen.

  • #2
    Das müsste gehen. Du kannst ja unter Select -> Random anklicken. Wenn du das mit einem Loop machst, der testet, wieviele Vertices ausgewählt sind, sollte das möglich sein.

    So gehts:
    Code:
    import bpy
    import random
    
    num = len(bpy.context.active_object.data.vertices)-1
    
    rnd = random.randint(0,num)
    
    bpy.ops.object.mode_set(mode = 'OBJECT')
    bpy.ops.object.mode_set(mode = 'EDIT')
    bpy.ops.mesh.select_mode(type="VERT")
    bpy.ops.mesh.select_all(action = 'DESELECT')
    bpy.ops.object.mode_set(mode = 'OBJECT')
    bpy.context.active_object.data.vertices[rnd].select = True
    bpy.ops.object.mode_set(mode = 'EDIT')

    EDIT: Ach jetzt sehe ich erst, dass du was ganz anderes willst. Thema verfehlt!
    Akt. Wettbewerb: Mobilität der Zukunft. Mein Blog: Downtown Blendpolis.

    Kommentar


    • #3
      own.meshes gibt dir nur eine Liste der Meshes eines Objekts, nicht deren Faces. Daher musst du noch auf die Polygone zugreifen, das geht wie folgt:
      Code:
      own.meshes[0].polygons
      Jedes Polygonobjekt (Achtung, das ist wieder eine Liste, d.h. du müsstest mit einer Schleife die Polygone durchgehen oder das gewollte Face direkt auswählen mit [index]) hat Attribute für die 3 Punkte (keine 4, in der Game Engine werden zur Laufzeit alle Quads und Ngons zu Tris konvertiert), mit etwas Mathe könntest du dann zwischen diesen Punkten um einen zufälligen Wert interpolieren.

      Ist aber glaube ich sehr kompliziert für das was du vermutlich machen willst. Ist es dir wichtig, dass jedes Face genau ein Landschaftsobjekt hat? Wenn nein, könntest du einfach um den Spieler mit Python (own.rayCast()) Rays von zufälligen Punkten über dem Mesh nach unten schicken und an den Hitpoints der Rays mit dem Boden-Mesh die Objekte spawnen. Rays können dir sogar den Normalenvektor des Schnittpunktes geben, du kannst die gespawnten Objekte damit sogar relativ leicht an die Ausrichtung des Bodens anpassen.
      Hab da vor einiger Zeit mal ein etwas umfangreicheres Skript geschrieben, wenn ich morgen Zeit hab kann ich das gerne raussuchen, vorausgesetzt das ist überhaupt das was du auch suchst. Musste mich mit den Erklärungen leider kurz fassen aus Zeitgründen, morgen kann ich dann gerne auch ausführlicher antworten
      Aktuelles Spieleprojekt "The Myth of Excalibur"

      Kommentar


      • #4
        Sry für die späte Antwort.

        Das mit den Rays von einem Objekt aus hab ich schon probiert. Das ist eigentlich ganz in Ordnung aber angenommen ein Ray geht ins Leere müsste ich das Script wiederholen lassen. Oder halt viele "Spawner" mit dem Script genauer an die Stellen setzen. Nicht allzu schlimm aber wenns einfacher gehen könnte wärs ganz gut.

        Zitat von Momel Beitrag anzeigen
        Ist es dir wichtig, dass jedes Face genau ein Landschaftsobjekt hat?
        Nein, nur eine bestimmte Anzahl. Blödes Beispiel: 2 Blumen auf einen Cubemesh, 2 random Faces auswählen, und jeweils eine Blume drauf platzieren.

        own.meshes[0].polygons
        Könntest du das detaillierter schreiben, ich krieg bei polygons oder polygons[0] nur Fehlermeldungen ingame: object has no attribut 'polygons' (ist aber ein Cube)
        Ist wichtig dass es ingame funktioniert damit ich das zeitlich kontrollieren kann.
        Im Grunde brauch ich sowas wie eine Art Vertex.worldPosition oder Face.worldPosition, gibts das überhaupt?
        Zuletzt geändert von Failsafe; 04.03.2018, 19:44.

        Kommentar


        • #5
          Also wenn dir das mit der genauen Anzahl nicht so wichtig wäre, würde ich sagen, dass du die Rays, die ins Leere treffen, einfach ignorierst. Da das aber nicht der Fall ist, wirds wirklich etwas komplizierter (zumindest wüsste ich nicht wie das ohne die Methoden von dir oder mir funktionieren sollte).

          Zum Attribut "polygons": Hab ausversehen aus Gewohnheit in die API der UPBGE (einer erweiterten und verbesserten Version der BGE; die API-Seite: Link) geguckt und nicht in die Blender-API (Link), da scheint es das Attribut tatsächlich nicht zu geben.

          Daher müsstest du das wie folgt schreiben:
          Code:
          mesh = own.meshes[0]
          for i in range(mesh.numPolygons):
              polygon = mesh.getPolygon(i)
          
              # Zugriff auf Vertices des jeweiligen Faces (leider umständlich, in der UPBGE aber genauso):
              mat_id = polygon.material_id
              vertex1 = mesh.getVertex(mat_id, polygon.v1)
              vertex2 = mesh.getVertex(mat_id, polygon.v2)
              vertex3 = mesh.getVertex(mat_id, polygon.v3)
              # ggf. (v4 = 0, wenn kein 4. Vertex vorhanden ist)
              vertex4 = mesh.getVertex(mat_id, polygon.v4)
          
              # Hier käme dann die Positionsbestimmung der Objekte hin
          (Nicht getestet, aber müsste funktionieren)

          Und vergiss das, was ich oben mit den 3 Punkten pro Polygon gesagt hab. Dass Game Engines Quads meist in Tris umwandeln stimmt zwar, hier scheint das aber keine Rolle zu spielen
          Zuletzt geändert von Momel; 04.03.2018, 20:11.
          Aktuelles Spieleprojekt "The Myth of Excalibur"

          Kommentar


          • #6
            Um eine Punkt auf einer Fläche zu bekommen ist es am einfachsten wenn man ein Dreieck hat. Dann hat man 3 Vertecies. Von V1 geht man um einen zufälligen Skalar in Richtung V2, und von dort um einen zufälligen Skalar in Richtung V3, und schon steht man irgendwo auf der Fläche. Da der Skalar zwischen 0 und 1 liegt, kann man nicht über das Ziel hinaus schießen.

            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: RanPoint.JPG Ansichten: 2 Größe: 9,9 KB ID: 12000Random Facepoint ( UpBGE Studie).zip

            Ich hab nur noch die UpBGE auf dem Rechner und und hab damit diesen Lösungsansatz umgesetzt. Auf Richtigkeit geb ich keine Garantie. Die Anzahl der zu "bepflanzenden" Flächen kann man einstellen, ebenso wie viel dort wachsen soll. Dazu hab ich einfach ein Listenobjekt durcheinander gewürfelt und die ersten X Flächen gezogen. So gibt es keine Doppelten. Um an die verwendeten Vertecies zu kommen hab ich "getPolygon(FaceNr).vertices" verwendet, und damit wie oben beschrieben, die Zufalls-Position auf der Fläche berechnet - so oft wie es eingestellt ist. Damit man das auch sieht habe ich die Koordinaten nach Global gerechnet, einen Empty dort hin verschoben und einen Cube adden lassen. ... so im Groben.

            Code:
            Faces = 30
            ItemsPerFace = 4
            
            # ~~~~~~~~~~~~~~
            
            import bge
            from random import uniform, shuffle
            
            def RandomIntersect(vA,vB):
            
                Richtung = vB - vA
                #Scalar = bge.logic.getRandomFloat()
                Scalar = uniform(0,1)
                return vA + Scalar * Richtung
            
            
            
            
            Cont = bge.logic.getCurrentController()
            Own = Cont.owner
            Mesh = Own.meshes[0]
            
            #print(dir(Own.orientation))
            
            FaceCount = int(Mesh.numPolygons/3)
            
            # select X random Faces
            ChosenFaces = list(range(FaceCount))
            shuffle(ChosenFaces)
            ChosenFaces = ChosenFaces[:Faces]
            
            # per Face
            for FaceNr in ChosenFaces:
                Vertex1, Vertex2, Vertex3 = Mesh.getPolygon(FaceNr).vertices
            
                # per Item ...
                for Item in range(ItemsPerFace):
                    Va = RandomIntersect(Vertex1.getXYZ(), Vertex2.getXYZ())
                    Vb = RandomIntersect(Va, Vertex3.getXYZ())
            
                    # Vb ist zufälliger Vector auf dem Face,
                    # zur weiteren Verarbeitung ... z.B.:
            
                    GlobalVb = Vb * Own.orientation.inverted() + Own.position
                    Emitter = bge.logic.getCurrentScene().objects["Emitter"]
                    Emitter.worldPosition = GlobalVb
            
                    bge.logic.getCurrentScene().addObject("Cube","Emitter",0)
            Meine Kanäle auf Vimeo und YouTube.

            Kommentar


            • #7
              Prima, das reicht mir vollkommen. Vielen Dank euch zwei.

              Kommentar

              Lädt...
              X