NodePath info in egg

Ok, I’ll start off with what I’m trying to do, then move on to my plans (and question) of how I intended to do it; that way if someone has a better way we can skip right to that ^^.

Essentially, I’m trying to build levels in a modelling program (3ds max8 ), then export them to Panda with the capability to script the whole level without the level editor phase of moving, rotating, and placing objects. To do this I am leaving markers in the modelling program indicating where I want things to be, from which I can create a node in Panda on the spot. Examples of the things I’m scripting in are save points, chests, boss location, start point, etc… The reason I am doing this is because I have a long list of very similar levels to create in a short amount of time (12 levels in 1 week, including level scripting and art)

At this point my troubles come in two spots. First, the 3ds max exporter does not handle Points, Dummies, or Splines; so the only way I can leave a marker is by putting visible geometry there. This I can deal with (make a small plane and flip it upside down), but it is a waste of resources compared to a single point. Second, even when I grab a marker location from the egg file, there is no rotational information that I can get from it. So even if I place objects in the right spot, there is a high likelihood that they will be facing in the wrong direction.

Assuming I’m going about this right, would it be easier to modify the exporter to include points and rotations (having little-no idea what I’m doing), to modify the egg file to include this information in a way useful to Panda, or to give up on exporting markers and just script each level. My biggest worry is time, so I’m looking for the fastest method and not necessarily the most efficient (eg. it may take longer to change, debug, and test new exporter functionality than just script the details…).

Thanks in advance,
~Silver~

May be, in a dirty way, you can use the normal of your small plane (the marker) to be the rotation information ?

Name your markers, say “Marker_xxx”, and in panda search it out, hide it, and parent your replaced object on it.

That should work. I’ll look into that, thanks.
I’m still wondering if there’s a better way to do this though…

soo…how exactly do I grab the normal information from the NodePath interface? Once I get the sub-node location all I have is the position. I’m sure there’s a way to get the normal from the Geom somehow, I’m just not seeing how to get it.

It’s probably easier to get this information from the raw egg file, by reading it using the EggData interface and related classes. You can walk the egg hierarchy to the particular EggPolygon, and extract the normal from that.

But, for retrieving position and rotation data, egg already has a syntax for this; when the tag is used in conjunction with a entry, it indicates that the transform has particular meaning and should be preserved exactly when the model is loaded into Panda. I don’t know if the 3DS converter has support for these syntaxes, though.

David

As far as I can tell, the 3ds max exporter does not support DCS/Transform functionality because in all of my many egg files they are never used once (unless I am supposed to set something specific in order for it to do that). The exporter is actually grouping all of my scene objects into one node object (“character”)…which is annoying since it defeats the purpose of searching for marker nodes. I’m having to go through and re-group my nodes in the egg files anyway. So, I’m thinking of manually putting in the DCS/Transform stuff into the egg…and hopefully all of my problems will be answered (its just gonna suck repeatedly going through the massive egg files…).

Good Luck to me ^^
~Silver~

…okay…so I’ve split up the object groupings of my egg file so that I can actually find my markers and other sub-nodes of the scene, but there is no transform data there at all. If it wouldn’t be too much of a hassle, could I get an example of how to properly format the DCS/Transform or Tag lines so that I can actually get this information from the egg file?

Further bad news is I thoroughly screwed up the egg file->node structure-
Before:

After:

There should only be around 30-40 nodes, but now it is taking every object in my scene and creating a seperate node for it. I’m not as worried about this now because its only an optimization issue, so I will be coming back to it later (I might even group by objects correctly by then, eliminating the problem). But if anyone knows why it’s happening or how to fix it, that would be a great help.

Thanks again,
~Silver~

If you create a dummy plane, you can try:

    node = environ.find("**/Plane")
    print node.getNetTransform()
    print node.getHpr()
    print node.getPos()

It works well with an egg I created with blender.

Even doing that, I get all zero’s for the transforms. I don’t think that the max-egg exporter conserves transforms (or at least the max8 one). This is why I wanted to try manually writing them in to the egg file, but I dont know the syntax since transform isn’t in the egg syntax page of the manual, and DCS is just a flag.

~Silver~

oic, so everything got transformed by the exporter and nothing left ? Can you post a sample egg file ?

kk, here’s one of my marker planes (since I’m assuming you don’t want the whole 30k+ line egg file). Note that I added the line since that seemed to be related to getting a node out of the geometry. All the other files are syntaxed in relatively the same way.

<Group> Start {
  <Dart> { 1 }
    <VertexPool> Start.verts {
      <Vertex> 0 {
        -26.781 -57.4234 0.5
        <Normal> { -0.5 -0.866025 -4.37114e-008 }
      }
      <Vertex> 1 {
        -26.781 -57.4234 -0.5
        <Normal> { -0.5 -0.866025 -4.37114e-008 }
      }
      <Vertex> 2 {
        -25.915 -57.9234 0.5
        <Normal> { -0.5 -0.866025 -4.37114e-008 }
      }
      <Vertex> 3 {
        -25.915 -57.9234 -0.5
        <Normal> { -0.5 -0.866025 -4.37114e-008 }
      }
    }
    <Polygon> {
      <RGBA> { 1 1 1 1 }
      <VertexRef> { 0 1 2 <Ref> { Start.verts } }
    }
    <Polygon> {
      <RGBA> { 1 1 1 1 }
      <VertexRef> { 3 2 1 <Ref> { Start.verts } }
    }
}

Thanks for all the help,
~Silver~

Quote from panda3d.cvs.sourceforge.net/view … iew=markup

The flag is necessary to indicate that this group begins an
animated model description. Without the flag, joints will be
treated as ordinary groups, and morphs will be ignored.

Here is the sample code to extract the required information:

from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "want-directtools #t")
loadPrcFileData("", "want-tk #t")

import direct.directbase.DirectStart
from pandac.PandaModules import *

from direct.task import Task
from direct.actor import Actor
from direct.interval.IntervalGlobal import *
import math

def getVertexInfo(np, relative=None):
    vertexinfo = []
    geomnode = np.node()
    nrgeoms = geomnode.getNumGeoms()
    for n in range(nrgeoms):
        geom = geomnode.getGeom(n)
        data = geom.getVertexData()
        numVtx = data.getNumRows()
        vtxReader=GeomVertexReader(data)
        # begin reading at vertex 0
        vtxReader.setRow(0)
        # get the vertex position column
        column=-1
        columnName=''
        while ( columnName!='vertex' ):
            column+=1
            vtxReader.setColumn(column)
            columnName=str(vtxReader.getColumn().getName())
        #=========================================================
        # create vertex normal reader
        normalReader=GeomVertexReader(data)
        # begin reading at vertex 0
        normalReader.setRow(0)
        # get the vertex normal column
        hasNormals=True
        column=-1
        columnName=''
        while ( columnName!='normal' ):
           column+=1
           normalReader.setColumn(column)
           if normalReader.getColumn()==None:
               hasNormals=False
               break
           else:
               columnName=str(normalReader.getColumn().getName())

        for i in range(numVtx):
            vtx = vtxReader.getData3f()
            if relative != None:
                vtx=relative.getRelativePoint(np,vtx)

            normal=normalReader.getData3f()
            if relative != None:
                normal=relative.getRelativeVector(np,normal)
            vertexinfo.append((vtx,normal))
        break
    return vertexinfo

class World():
    def __init__(self):
        environ = loader.loadModel("test6.egg")
        environ.reparentTo(render)

        node = environ.find("**/Start")
        node = node.getChild(0) # since it is a character node, the geomnode is the first child.
        info = getVertexInfo(node,render)
        print info

w = World()
run()

Thanks alot for the eggSyntax link, it told me what I was doing wrong that caused the excess node problem. Also, thanks for the vertex collection code. I should be able to get my tranform info from that without having to re-write/edit all of my egg files. You don’t mind if I use the code (with some slight modifications), do you?

~Silver~

The code is from the Code Snipplets forum, just do what you want, and don’t credit me.

While information about dummy nodes is definitely supported by other exporters (like the one for Blender,) it may be easier in 3ds max to simply write a MaxScript to export this information out. In the past it had taken me all of half an hour to writes scripts to do this for both Maya and Blender, and that includes the time it took me to learn the MEL commands I needed.