Advice needed throughout my first 3D project

Everything related to 3D programming
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Advice needed throughout my first 3D project

Post by Seymour Clufley »

Hello everyone,

This is a project that is very new for me. I have very little experience of 3D graphics, but I do know a lot about PureBasic in general, XML, 2D graphics and SVG. However, I don't know how to proceed with this project or which tools to use. I don't even know if PB should be involved, though to retain control and options for myself I think it probably should be, rather than using third party software. So, here are some questions before I begin.

WHAT I'M STARTING WITH
A very complex 2D "map" of a town, in SVG format. The elements are coloured according to their elevation, so ground level is grey, elevated platforms are white with black dots, buildings are yellow, etc. - this is all very consistent. Here is a sample of the map:

Image

WHAT I WANT TO END UP WITH
A 3D scene derived from the SVG. There is an infinite plane denoting "land", and the sky is pure blue. I can move around the town quite freely. The current camera position and orientation can be retrieved and set so that I can quickly return to "favourite" places later on. I can take screenshots or renders; one thing I might like to have is distance blur.

Obviously I could use a 3D CAD program to recreate the town in 3D manually, but that seems insane given that it would be much easier to write a PB program that automatically processed the SVG file and output a 3D version in some way. The height and Y-position of each element could be set according to its colour. For example, elevated platforms, identified by their white-with-black-dots colouring, would be at 10 feet above ground level and 2 feet thick, etc.

So the questions relating to PB's 3D engine...
  • can the current camera position/orientation be retrieved and set?
  • can distance blur be achieved? (It needn't be used all the time, just when I press "render".)
  • in 2D most of the elements (buildings, platforms, etc.) are rectangles, but some are more complex polygons. Obviously these would need to be translated into 3D shapes. I'm sure cuboids could be created on the fly in PB, but what about complex shapes?
  • in the SVG, the roads have a "texture" such that the white dashed line follows the direction of the road. Could this be emulated in PB?
  • is there a way to identify which shape is currently under the mouse cursor?
As you can see, it's all up in the air just now, so any advice would be welcome.
Last edited by Seymour Clufley on Sat Oct 05, 2013 5:23 pm, edited 1 time in total.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Advice needed before I begin a project

Post by IdeasVacuum »

Although the principle is simple, it's a lot of work to code that from scratch. 3D geom in a CAD program would be described with surfaces/solids. PB supports meshing, so you will need to triangulate every individual wall extruded, though the triangles can be giant (2 triangles describe a rectangle = wall face). I would do it in that way since the shape of the building (perimeter/plan view) is then not an issue for flat walls. Walls with curvature present another challenge.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Advice needed before I begin a project

Post by Samuel »

Seymour Clufley wrote: [*]can the current camera position/orientation be retrieved and set?
Yes, there are many camera commands that will cover pretty much everything you'll ever need. Here's a link.
http://www.purebasic.com/documentation/camera/
Seymour Clufley wrote: [*]can distance blur be achieved? (It needn't be used all the time, just when I press "render".)
Do you mean Anisotropic Filtering or something like a compositor blurring effect. Both are possible with the OGRE engine.
I'm just not exactly sure if that's what you want.
Seymour Clufley wrote: [*]in 2D most of the elements (buildings, platforms, etc.) are rectangles, but some are more complex polygons. Obviously these would need to be translated into 3D shapes. I'm sure cuboids could be created on the fly in PB, but what about complex shapes?
You'll have to create your own routine for creating complex shapes. Creating the shapes themselves is easy with PureBasic.
It just takes a little practice to learn how to create your own normals and UV coordinates.
Seymour Clufley wrote: [*]in the SVG, the roads have a "texture" such that the white dashed line follows the direction of the road. Could this be emulated in PB?
If you create your own mesh then you will also need to add UV coordinates to the mesh. Then using those UV coordinates you can add any texture you want to the mesh.
Seymour Clufley wrote: [*]is there a way to identify which shape is currently under the mouse cursor?[/list]
I believe MousePick(#Camera, x, y [, PickMask]) is what your after.
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Advice needed before I begin a project

Post by Seymour Clufley »

Alexi wrote:Much easier is to convert the Svg to 3D with a CAD program. Here you can directly optimize everything and split up all Elements. Curves are also done with it.

If you send me the SVG i could try it for you. But it's easier if you remove the hachures if they aren't paths.
Thanks very much for the offer, Alexi, but I want to do this with PB. I've realised this is the only way I can get the sort of control and flexibility that I need.
I see some overlapping "Bridges" same colored as the Buildings. If the color specifies the height it would look a little strange.
This is an example of why I want to use PB. All I need to do with the bridges is specify that each one is a bridge (an XML attribute, something like "type=bridge") and I can write into the PB procedure that a bridge should be created a certain way.
Seymour Clufley wrote:distance blur
Samuel wrote:Do you mean Anisotropic Filtering or something like a compositor blurring effect. Both are possible with the OGRE engine.
I'm just not exactly sure if that's what you want.
I mean this sort of thing, where the objects become blurry the further away they are from the camera. Is that sort of thing possible?
You'll have to create your own routine for creating complex shapes. Creating the shapes themselves is easy with PureBasic.
It just takes a little practice to learn how to create your own normals and UV coordinates.
Thanks for the encouragement (and to IdeasVacuum, for the same). I've been making some first steps to learn how to do this.

I've been trying to create a simple cube mesh. (I know there's the CreateCube command, but I need to do this the hard way first as a practice for more complex polygons.) The trouble I'm having is that the sides disappear and reappear as the cube is rotated. I think this might be because the texture is applied to only one side of each face... if so, is there any way to avoid this happening? Here's the code I've got, adapted from an example, and it should demonstrate the problem:

Code: Select all

InitEngine3D()
InitSprite()

win = OpenWindow(#PB_Any,0,0,800,600,"Cube",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(win),0,0,800,600)

cam = CreateCamera(#PB_Any,0,0,100,100)
CameraRange(cam,0,2000)
CameraProjectionMode(cam,#PB_Camera_Perspective)

tex = CreateTexture(#PB_Any,1024,1024)
If StartDrawing(TextureOutput(tex))
	DrawingMode(#PB_2DDrawing_Gradient)
	BackColor(#Red)
	FrontColor(#Yellow)
	CircularGradient(512,512,256)
	Box(0,0,1024,1024)
	StopDrawing()
EndIf
mat = CreateMaterial(#PB_Any,TextureID(tex))
DisableMaterialLighting(mat,#True)


Structure VectorF
	x.f
	y.f
	z.f
EndStructure

Procedure.b MakeMeshRectangularSide(msh,Array corner.VectorF(1))
	
	MeshVertexPosition(corner(1)\x,corner(1)\y,corner(1)\z)
	MeshVertexTextureCoordinate(0,0)
	
	MeshVertexPosition(corner(2)\x,corner(2)\y,corner(2)\z)
	MeshVertexTextureCoordinate(1,0)
	
	MeshVertexPosition(corner(3)\x,corner(3)\y,corner(3)\z)
	MeshVertexTextureCoordinate(1,1)
	
	MeshVertexPosition(corner(4)\x,corner(4)\y,corner(4)\z)
	MeshVertexTextureCoordinate(0,1)
	
	vertices = MeshVertexCount(msh)
	MeshFace(vertices-3,vertices-1,vertices-2)
	MeshFace(vertices-3,vertices,vertices-1)
	
EndProcedure

Procedure.i CuboidalMesh(xd.f,yd.f,zd.f)
	
	msh = CreateMesh(#PB_Any,#PB_Mesh_TriangleList,#PB_Mesh_Dynamic)
	Dim corner.VectorF(4)
	
	
	; front
	corner(1)\x = 0
	corner(1)\y = 0
	corner(1)\z = 0
	
	corner(2)\x = xd
	corner(2)\y = 0
	corner(2)\z = 0
	
	corner(3)\x = xd
	corner(3)\y = yd
	corner(3)\z = 0
	
	corner(4)\x = 0
	corner(4)\y = yd
	corner(4)\z = 0
	
	MakeMeshRectangularSide(msh,corner())
	
	
	; back
	corner(1)\x = 0
	corner(1)\y = 0
	corner(1)\z = zd
	
	corner(2)\x = xd
	corner(2)\y = 0
	corner(2)\z = zd
	
	corner(3)\x = xd
	corner(3)\y = yd
	corner(3)\z = zd
	
	corner(4)\x = 0
	corner(4)\y = yd
	corner(4)\z = zd
	
	MakeMeshRectangularSide(msh,corner())
	
	
	; top
	corner(1)\x = 0
	corner(1)\y = yd
	corner(1)\z = 0
	
	corner(2)\x = xd
	corner(2)\y = yd
	corner(2)\z = 0
	
	corner(3)\x = xd
	corner(3)\y = yd
	corner(3)\z = zd
	
	corner(4)\x = 0
	corner(4)\y = yd
	corner(4)\z = zd
	
	MakeMeshRectangularSide(msh,corner())
	
	
	; bottom
	corner(1)\x = 0
	corner(1)\y = 0
	corner(1)\z = 0
	
	corner(2)\x = xd
	corner(2)\y = 0
	corner(2)\z = 0
	
	corner(3)\x = xd
	corner(3)\y = 0
	corner(3)\z = zd
	
	corner(4)\x = 0
	corner(4)\y = 0
	corner(4)\z = zd
	
	MakeMeshRectangularSide(msh,corner())
	
	
	; left side
	corner(1)\x = 0
	corner(1)\y = 0
	corner(1)\z = 0
	
	corner(2)\x = 0
	corner(2)\y = 0
	corner(2)\z = zd
	
	corner(3)\x = 0
	corner(3)\y = yd
	corner(3)\z = zd
	
	corner(4)\x = 0
	corner(4)\y = yd
	corner(4)\z = 0
	
	MakeMeshRectangularSide(msh,corner())
	
	
	; right side
	corner(1)\x = xd
	corner(1)\y = 0
	corner(1)\z = 0
	
	corner(2)\x = xd
	corner(2)\y = 0
	corner(2)\z = zd
	
	corner(3)\x = xd
	corner(3)\y = yd
	corner(3)\z = zd
	
	corner(4)\x = xd
	corner(4)\y = yd
	corner(4)\z = 0
	
	MakeMeshRectangularSide(msh,corner())
	
	
	FinishMesh(#True)
	ProcedureReturn msh
	
EndProcedure


msh = CuboidalMesh(100,100,100)
ent = CreateEntity(#PB_Any,MeshID(msh),MaterialID(mat),-50,-50,-500)

xdeg.f = 0.25
ydeg.f = 2.5
zdeg.f = 1
Repeat
	If GetAsyncKeyState_(#VK_ESCAPE) : Break : EndIf
	If we = #PB_Event_CloseWindow : Break : EndIf
	RotateEntity(ent,xdeg,ydeg,zdeg,#PB_Relative)
	RenderWorld()
	FlipBuffers()
	Delay(10)
ForEver
If I'm right about why this is happening, then the problem would probably be in the last two lines of the MakeMeshRectangularSide() procedure. Thanks in advance to anyone who can help.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Advice needed before I begin a project

Post by Samuel »

Seymour Clufley wrote: The trouble I'm having is that the sides disappear and reappear as the cube is rotated. I think this might be because the texture is applied to only one side of each face... if so, is there any way to avoid this happening? Here's the code I've got, adapted from an example, and it should demonstrate the problem:
Your correct when you face an object you need to make sure it's facing the right direction.
If you don't want to calculate the direction you can just face both sides of the triangle.

Replace this code

Code: Select all

	MeshFace(vertices-3,vertices-1,vertices-2)
	MeshFace(vertices-3,vertices,vertices-1)
with this

Code: Select all

   MeshFace(vertices-3,vertices-1,vertices-2)
   MeshFace(vertices-3,vertices-2,vertices-1)
   MeshFace(vertices-3,vertices,vertices-1)
   MeshFace(vertices-3,vertices-1,vertices)
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Advice needed before I begin a project

Post by Seymour Clufley »

Thanks very much for that, Samuel.

One more question. Do you (or anyone else) have PB code for triangulating/tessellating a polygon? I've found a very lengthy C++ function but I don't know C++ so can't translate it. There's also a JavaScript function but it's massive at 2000 lines. This seems like a wheel that must already have been invented by someone in the PB community...
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Advice needed before I begin a project

Post by Samuel »

I've been working with different triangulation methods for over the last year and a half. So, I know a little bit about them.

Do you know the exact shape and pattern of the polygons? If not it's quite a process to calculate the triangulation of a polygon.
Speed can also be an issue depending on how many points the polygon has. I'm talking thousands of points not a couple.

I have had a lot of success with the Delaunay triangulation method.
Unfortunately, I can't give you my source code because it's for a commercial project.
Here's a link if you would like to get some info and look over the algorithm.
http://en.wikipedia.org/wiki/Delaunay_triangulation
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Advice needed before I begin a project

Post by applePi »

Seymour Clufley wrote: sides disappear and reappear as the cube is rotated
also use #PB_Material_NoCulling to see the back sides in general,

Code: Select all

MaterialCullingMode(mat, #PB_Material_NoCulling  )
PS: to have a rough and approximate way to see how your picture will appear as a 3D model, load it in irfanview and change it to negative, copy it to the textures folder and load the example "TerrainHeight.pb" then replace the picture in line 78 with your picture:
Imported = DefineTerrainTile(0, tx, ty, "MyTown.jpg", ty % 2, tx % 2)
and increase camera speed to 10
#CameraSpeed = 10 line 16
if you go high enough you will see this terrain:
Image

but there are too much spikes and sharp edges, i wonder if there are more adjustments to make it more correct !!
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Advice needed before I begin a project

Post by IdeasVacuum »

...you will only need smarter triangulation for regions of Objects that have curvature, and then it gets down to how fine the resolution needs to be. Since you are extruding from a plan view, it should not be so difficult - build the curvature region out of 'flat strips', each strip is only 2 triangles.

Image
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Advice needed before I begin a project

Post by Samuel »

What about a triangulation method for the top of the building? As you said the sides of the building are simple, but if you want an triangulation method for the top
it can be more complex. Depending on the shape and amount of points. Unless he manually specifies the triangles in which case it won't be that difficult.
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Advice needed before I begin a project

Post by Seymour Clufley »

Samuel, this is what I'm trying to tackle in this thread.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Advice needed before I begin a project

Post by IdeasVacuum »

...To triangulate any irregular 2D polygon (roof), find it's (approximate) center and then your triangle edges eminate from that center point to each corner point of the polygon.

Image
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Advice needed before I begin a project

Post by IdeasVacuum »

...there is a good book on this subject:
Computational Geometry in C
(Don't worry about the C), your local library should be able to find it for you.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Advice needed before I begin a project

Post by Samuel »

IdeasVacuum wrote:...To triangulate any irregular 2D polygon (roof), find it's (approximate) center and then your triangle edges eminate from that center point to each corner point of the polygon.
That will work for most basic polygons, but there are many that can get around that logic.

Here's an example picture.
Image

The red circle is about the center and as you can tell is outside the polygon. So, in a case like this you'll need something more advanced.
I'd recommend that he continue trying to get a routine that can triangulate any possible polygon.
It looks like that book you referenced might have some nice methods.
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Advice needed before I begin a project

Post by Seymour Clufley »

Thanks, IV. That method would certainly work for convex polygons. It's the concave ones I'm worried about - but there are apparently ways to split a concave polygon into multiple convex ones.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Post Reply