Tiles

Is there a built in “tile” system for panda3D like in 2D game development, such that, if I have a plane I want to tile x, y, (or x, z, or y, z), my planes won’t get black edges between them and look like garbage? If not, is there a better way to do this? I kind of gave up on attempting to export an entire room from Blender. This one is kind of all over the place with the errors I’m getting from it. Thank you for your time!

I’m not sure what you’re asking. “black edges between them and look like garbage” isn’t a very helpful description of your problem. We need to know what you’re doing, what you expect, and what’s actually happening. There are many different ways to implement a tiled system in a 3d environment, and how to solve the problem depends on which one you chose.

As a random stab in the dark: is the model you’re using for a plane large enough to actually make it to the next tile? If you have tiles spaced 1 unit apart but the model is only 0.99 long, then it will show the gap most of the time. You could try inspecting the .egg file to see if you have rounding errors.

Here’s an image of the problem. As far as I know, blender is exporting them appropriately. But I’ll check to make sure.

I guess I’ll just paste my whole level class, may as well, just in case.

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
class Level(DirectObject):
    def __init__(self, leveltype, mapname, dimX, dimY, dimZ):
        self.levelroot = render.attachNewNode("Level Root")
        self.floorname = "models/" + leveltype + "/floor.egg"
        self.wallname = "models/" + leveltype + "/wall.egg"
        self.levelfloor = [[0 for col in range(dimY)] for row in range(dimX)]
        self.walls = [0 for num in range(dimX*dimZ*2 + dimY*dimZ*2)]
        num = 0
        for x in range(dimX):
            for y in range(dimY):
                if x == 0 or x+1 == dimX or y == 0 or y+1 == dimY:
                    for z in range(dimZ):
                        self.walls[num] = loader.loadModel(self.wallname)
                        self.walls[num].setPos(x,y,z)
                        if y == 0 or y+1 == dimY:
                            self.walls[num].setH(90)
                        self.walls[num].reparentTo(self.levelroot)
                        num += 1
                    if (x == 0 or x + 1 == dimX) and (y == 0 or y+1 == dimY):
                        for z in range(dimZ):
                            self.walls[num] = loader.loadModel(self.wallname)
                            self.walls[num].setPos(x,y,z)
                            self.walls[num].reparentTo(self.levelroot)
                            num += 1 
                self.levelfloor[x][y] = loader.loadModel(self.floorname)
                self.levelfloor[x][y].setPos(x,y,0)
                self.levelfloor[x][y].reparentTo(self.levelroot)
        self.levelroot.setScale(3)

I checked, and that’s a negative, unless there’s a “negligible” difference in the size of a panda unit and a blender unit.

What are your textures like? If they have a back border, this might be the cause of it. Alternatively, you could have set the texture wrap mode to fill at some point somewhere, but this seems unlikely.

You could try setting panda’s fill colour to red (base.setBackgroundColor(1,0,0,1)) and seeing if the black lines become red. If so, it’s definitely your geometry that has gaps in it. Try using cardMaker to construct your tiles and see if the problem still exists.

I can’t get Yabee to export a “generated” textured mesh properly, the thing always ends up doing a disappearing act when pview comes up, so I had to UV map the planes. I probably should’ve come to the forums for help on this sooner, but I was all, “nah, I got this.” There’s not any sort of intrusively colored border on them.

The background right now outside the tiled area is 0, 255, 0, so I don’t know if that’s the issue. And what is cardMaker? Is it hard to learn?

Sounds to me like you’re running into floating point errors. Would you mind pasting the .egg file you’re using here? They’re just text files, and it should be short enough.

Oh, God. Even just looking at the file I can see where it could very definitely be going wrong. =(

They’re both based on the same tile, so I’ll just post this one for brevity.

<CoordinateSystem> { Z-up } 
<Material> Material {
  <Scalar> diffr { 0.640000 }
  <Scalar> diffg { 0.640000 }
  <Scalar> diffb { 0.640000 }
  <Scalar> specr { 0.500000 }
  <Scalar> specg { 0.500000 }
  <Scalar> specb { 0.500000 }
  <Scalar> shininess { 12.5 }
  <Scalar> emitr { 0.000000 }
  <Scalar> emitg { 0.000000 }
  <Scalar> emitb { 0.000000 }
}

<Texture> Tex {
  "./tex/floor.png"
  <Scalar> envtype { MODULATE }
  <Scalar> minfilter { LINEAR_MIPMAP_LINEAR }
  <Scalar> magfilter { LINEAR_MIPMAP_LINEAR }
  <Scalar> wrap { REPEAT }
}

  <Group> Cube {
    <Transform> {
      <Matrix4> {
        0.500000 0.000000 0.000000 0.000000 
        0.000000 0.500000 0.000000 0.000000 
        0.000000 0.000000 0.050000 0.000000 
        -0.000000 -0.000000 0.000000 1.000000 
      }
    }
    
    <VertexPool> Cube {
    
      <Vertex> 0 {
        0.4999999701976776 0.4999995529651642 -0.0005000000237487257
        
        <UV>  {
          0.999900 0.999899
        }
      }
      <Vertex> 1 {
        -0.4999997019767761 0.49999985098838806 -0.0005000000237487257
        
        <UV>  {
          0.000100 0.999900
        }
      }
      <Vertex> 2 {
        -0.49999991059303284 -0.49999964237213135 -0.0005000000237487257
        
        <UV>  {
          0.000100 0.000100
        }
      }
      <Vertex> 3 {
        0.49999940395355225 -0.5000001192092896 -0.0005000000237487257
        
        <UV>  {
          0.999899 0.000100
        }
      }
      <Vertex> 4 {
        0.49999940395355225 -0.5000001192092896 0.0
        
        <UV>  {
          0.999899 0.000100
        }
      }
      <Vertex> 5 {
        -0.49999991059303284 -0.49999964237213135 0.0
        
        <UV>  {
          0.000100 0.000100
        }
      }
      <Vertex> 6 {
        -0.4999997019767761 0.49999985098838806 0.0
        
        <UV>  {
          0.000100 0.999900
        }
      }
      <Vertex> 7 {
        0.4999999701976776 0.4999995529651642 0.0
        
        <UV>  {
          0.999900 0.999899
        }
      }
      <Vertex> 8 {
        -0.4999997019767761 0.49999985098838806 -0.0005000000237487257
        
        <UV>  {
          0.000100 0.999900
        }
      }
      <Vertex> 9 {
        0.4999999701976776 0.4999995529651642 -0.0005000000237487257
        
        <UV>  {
          0.999900 0.999899
        }
      }
      <Vertex> 10 {
        0.4999999701976776 0.4999995529651642 0.0
        
        <UV>  {
          0.999900 0.999899
        }
      }
      <Vertex> 11 {
        -0.4999997019767761 0.49999985098838806 0.0
        
        <UV>  {
          0.000100 0.999900
        }
      }
      <Vertex> 12 {
        0.4999999701976776 0.4999995529651642 -0.0005000000237487257
        
        <UV>  {
          0.999900 0.999899
        }
      }
      <Vertex> 13 {
        0.49999940395355225 -0.5000001192092896 -0.0005000000237487257
        
        <UV>  {
          0.999899 0.000100
        }
      }
      <Vertex> 14 {
        0.49999940395355225 -0.5000001192092896 0.0
        
        <UV>  {
          0.999899 0.000100
        }
      }
      <Vertex> 15 {
        0.4999999701976776 0.4999995529651642 0.0
        
        <UV>  {
          0.999900 0.999899
        }
      }
      <Vertex> 16 {
        0.49999940395355225 -0.5000001192092896 -0.0005000000237487257
        
        <UV>  {
          0.999899 0.000100
        }
      }
      <Vertex> 17 {
        -0.49999991059303284 -0.49999964237213135 -0.0005000000237487257
        
        <UV>  {
          0.000100 0.000100
        }
      }
      <Vertex> 18 {
        -0.49999991059303284 -0.49999964237213135 0.0
        
        <UV>  {
          0.000100 0.000100
        }
      }
      <Vertex> 19 {
        0.49999940395355225 -0.5000001192092896 0.0
        
        <UV>  {
          0.999899 0.000100
        }
      }
      <Vertex> 20 {
        -0.49999991059303284 -0.49999964237213135 -0.0005000000237487257
        
        <UV>  {
          0.000100 0.000100
        }
      }
      <Vertex> 21 {
        -0.4999997019767761 0.49999985098838806 -0.0005000000237487257
        
        <UV>  {
          0.000100 0.999900
        }
      }
      <Vertex> 22 {
        -0.4999997019767761 0.49999985098838806 0.0
        
        <UV>  {
          0.000100 0.999900
        }
      }
      <Vertex> 23 {
        -0.49999991059303284 -0.49999964237213135 0.0
        
        <UV>  {
          0.000100 0.000100
        }
      }}
    
    
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {0.000000 0.000000 1.000000}
      <VertexRef> { 0 1 2 3 <Ref> { Cube }}
    }
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {0.000000 0.000000 -1.000000}
      <VertexRef> { 4 5 6 7 <Ref> { Cube }}
    }
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {-0.000000 -1.000000 0.000000}
      <VertexRef> { 8 9 10 11 <Ref> { Cube }}
    }
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {-1.000000 0.000001 0.000000}
      <VertexRef> { 12 13 14 15 <Ref> { Cube }}
    }
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {0.000001 1.000000 0.000000}
      <VertexRef> { 16 17 18 19 <Ref> { Cube }}
    }
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {1.000000 -0.000000 0.000000}
      <VertexRef> { 20 21 22 23 <Ref> { Cube }}
    }
  }

If this is the problem, is there anything I can even do about it?

Ohhh haha I see now. The black lines are probably gaps between the tiles. It’s showing the unlit side of your cube.

You could either go through and round them to the nearest correct value by hand or try this one instead. It’s a plane instead of a cube, so it only has one face.

<CoordinateSystem> { Z-up }
<Material> Material {
  <Scalar> diffr { 0.640000 }
  <Scalar> diffg { 0.640000 }
  <Scalar> diffb { 0.640000 }
  <Scalar> specr { 0.500000 }
  <Scalar> specg { 0.500000 }
  <Scalar> specb { 0.500000 }
  <Scalar> shininess { 12.5 }
  <Scalar> emitr { 0 }
  <Scalar> emitg { 0 }
  <Scalar> emitb { 0 }
}

<Texture> Tex {
  "./tex/floor.png"
  <Scalar> envtype { MODULATE }
  <Scalar> minfilter { LINEAR_MIPMAP_LINEAR }
  <Scalar> magfilter { LINEAR_MIPMAP_LINEAR }
  <Scalar> wrap { REPEAT }
}

  <Group> Plane {
    <Transform> {
      <Matrix4> {
        1 0 0 0 
        0 1 0 0 
        0 0 1 0 
        0 0 0 1 
      }
    }
    
    <VertexPool> Plane {    
      <Vertex> 0 { -0.5 -0.5 0.0        
        <UV>  {0.000 0.000}
      }
      <Vertex> 1 { 0.5 -0.5 0.0        
        <UV>  {1.0 0.0}
      }
      <Vertex> 2 {0.5 0.5 0.0
	  <UV>  { 1.0 1.0 }
      }
      <Vertex> 3 {-0.5 0.5 0.0        
        <UV>  {0.0 1.0}
      }
	}
    
    <Polygon> {
      <TRef> { Tex }
      <MRef> { Material }
      <Normal> {0 0 1}
      <VertexRef> { 0 1 2 3 <Ref> { Plane }}
    }
  }

Ohhh… When I applied the solidify modifier that must have turned it into a cube. :blush: What would I do to texture it?

Edit: Oh, derp, you already did that part for me. xD

edit: never mind. Also, there was a typo in my egg file. One of the UV coordinates was wrong, on vertex 3. It’s fixed now.

Here’s a fun new issue. :frowning: The floor is cut up into a diagonal half, with one half looking (I think) normal, and the other very streaky.

Though, it did solve the arbitrary black space issue! =D

See my previous post about the typo. I should have learned by now hot to write them by hand, but oh well. You just need to change the UV block on vertex 3. It’s meant to read “0.0 1.0”, not “0.0 0.1”.

Awesome! Thank you so much! I guess I’ll continue with my tile system. I like the way it looks, and I like the flexibility of what I’m going to be able to do with it. Unless the tiling takes up too many resources? Or do you think having that many individual planes should be okay? (I hear that it’s better to have more vertices on one mesh than more meshes with fewer vertices or something.)

Modern graphics cards like you to have few meshes with many vertices, yes. You will run into speed slowdowns when you start to have many (~300 according to the manual) individual meshes.

You can flatten them all into one mesh by calling node.clearModelNodes() and then node.flattenStrong() on the parent of all of your tiles after you have loaded them all in.

Now a couple of my walls become invisible. :frowning:
I tried using node.setTwoSided(True), and then the invisible walls were just black. I feel like I must be doing something horribly wrong.

Before you enabled double sided rendering, you looked at the back faces, which are not rendered by default. That optimization is called backface culling. Where is back or front of a polygon is decided by its normal.
If a two sided plane appears black, then that’s probably caused by flipped face normals and no backface culling. You’re basically looking at the unlit side of the wall.

Try to either fix that in blender -which is the proper way- or, if your walls are axis aligned, scale them along their normal by -1 by using NodePath methods (given each wall is a single node) or by editing the egg file.

I just set a variable to change the heading of the tiles based on which way the walls should be facing (depending on whether they were at upper or lower x bounds), and it works really well now. If anyone is following this who is interested in my code, to use or optimize (or even just to tell me how horrible my code is!), let me know and I’d be glad to post it. =] My level class has come a long way during the past couple days when it comes to room generation, and I’d like to thank everyone for all of your extremely prompt feedback on my issues! =D I’m sure I’ll be back soon with some new and fun error I’m getting, probably in regards to collision detection! =P This is all really exciting, and I’m glad there’s a pretty strong community (from what I’ve seen so far) who is willing to help someone fairly new to 3D game programming and 3D model creation.