MiniB3d for FreeBasic

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

EntityBox is implemented only for the destination entity, not for the moving one. Supported collisions are sphere to sphere, sphere to box and sphere to geometry. You were trying to do box to sphere, that isn't supported
Gunslinger
Posts: 107
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

got it, Any idea why createconstraints are not keeping the box at place ?
making the cube feets it one entity is also not working for me.
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

Because the constraints affects the pivots, not their parent entities.

The pivots should not be children of player, they should be independent entities, and then you should use CreateRigidBody to use them as a reference for the player entity (you need four pivots: one for the position, and three for the x,y, and z axis)

Have a look at this example:

Code: Select all

#include "openb3d.bi"




screen 18,  32, , &h10002 

	
Graphics3d 640,480,32,1,1

var camera=createcamera(0)
var cube=createcube()


dim piv(8) as any ptr
for i as integer=1 to 8
	piv(i)=createpivot()
	entitytype piv(i),1
	entityradius piv(i),.01
next

positionentity piv(1),-1,-1,-1
positionentity piv(2), 1,-1,-1
positionentity piv(3),-1, 1,-1
positionentity piv(4), 1, 1,-1
positionentity piv(5),-1,-1, 1
positionentity piv(6), 1,-1, 1
positionentity piv(7),-1, 1, 1
positionentity piv(8), 1, 1, 1



for i as integer=1 to 8
	actvector piv(i),0,-.01,0
	actnewtonian piv(i),.9
	for i2 as integer=i+1 to 8
		createconstraint piv(i),piv(i2), entitydistance(piv(i),piv(i2))
	next
next 

createrigidbody cube,piv(1),piv(2),piv(3),piv(5)
fitmesh cube,0,0,0,1,1,1





var cube2=createcube()


dim piv2(8) as any ptr
for i as integer=1 to 8
	piv2(i)=createpivot()
	entitytype piv2(i),1
	entityradius piv2(i),.01
next

positionentity piv2(1), 2,-1,-1
positionentity piv2(2), 4,-1,-1
positionentity piv2(3), 2, 1,-1
positionentity piv2(4), 4, 1,-1
positionentity piv2(5), 2,-1, 1
positionentity piv2(6), 4,-1, 1
positionentity piv2(7), 2, 1, 1
positionentity piv2(8), 4, 1, 1



for i as integer=1 to 8
	actvector piv2(i),0,-.01,0
	actnewtonian piv2(i),.9
	for i2 as integer=i+1 to 8
		if i<>i2 then createconstraint piv2(i),piv2(i2), entitydistance(piv2(i),piv2(i2))
	next
next 






createrigidbody cube2,piv2(1),piv2(2),piv2(3),piv2(5)
fitmesh cube2,0,0,0,1,1,1
updateworld
renderworld

entitytype cube,-2
entitytype cube2,-2

var plane=createplane()':scaleentity plane, 100,.1,100
entitytype plane,-2

moveentity plane,0,-4,15
entitycolor plane,255,0,0

collisions 1,2,1,3


var light=createlight()
positionentity light,5,5,5
pointentity light,cube
moveentity camera,0,2,-15
pointentity camera,cube

var s=createcube
positionentity s,3,-3,0
scaleentity s,2,1,2
entitytype s,-2
'turnentity plane,0,0,10

dim key as string
do




	key=inkey
        if key=chr(255)+"H" then moveentity s,0,0,.1
        if key=chr(255)+"P" then moveentity s,0,0,-.1
        if key=chr(255)+"M" then moveentity s,.1,0,0
        if key=chr(255)+"K" then moveentity s,-.1,0,0
	updateworld 1


	renderworld
	sleep 1
	flip
loop until key=chr(27)

Gunslinger
Posts: 107
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

angros47 wrote: Jan 09, 2024 16:31 Because the constraints affects the pivots, not their parent entities.

The pivots should not be children of player, they should be independent entities, and then you should use CreateRigidBody to use them as a reference for the player entity (you need four pivots: one for the position, and three for the x,y, and z axis)

Have a look at this example:
Yeah this is really unusable for any game making i think.
Setting "entitytype cube2, -2" to "entitytype cube2, 2" make them stop dancing on the floor.
cubes kind of losing speed then turning.
Setting gravity with ACTTRACKBYPOINT is making them trip out.
Think createrigidbody better be removed at this point.

Going to give this a try, viewtopic.php?f=14&t=22473
Joshy did a nice job on documentation and supports concave shapes, what i need for train collision
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

Sorry it didn't help. Let me know if you have more luck with TrueAxis, or Newton, or ODE.
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

This example should work a bit better. By the way, if you need a complete physics engine, you would indeed need an external libraries. The functions provided by OpenB3D are mostly for collision detections

Code: Select all

#include "openb3d.bi"




screen 18,  32, , &h10002 

	
Graphics3d 640,480,32,1,1

var camera=createcamera(0)
var cube=createcube()


dim piv(8) as any ptr
for i as integer=1 to 8
	piv(i)=createpivot()
	entitytype piv(i),1
	entityradius piv(i),.01
next

positionentity piv(1),-1,-1,-1
positionentity piv(2), 1,-1,-1
positionentity piv(3),-1, 1,-1
positionentity piv(4), 1, 1,-1
positionentity piv(5),-1,-1, 1
positionentity piv(6), 1,-1, 1
positionentity piv(7),-1, 1, 1
positionentity piv(8), 1, 1, 1



for i as integer=1 to 8
	actvector piv(i),0,-.01,0
	actnewtonian piv(i),.9
	for i2 as integer=i+1 to 8
		if i2<>i then createconstraint piv(i),piv(i2), entitydistance(piv(i),piv(i2))
	next
next 

createrigidbody cube,piv(1),piv(2),piv(3),piv(5)
fitmesh cube,0,0,0,1,1,1





var cube2=createcube()


dim piv2(8) as any ptr
for i as integer=1 to 8
	piv2(i)=createpivot()
	entitytype piv2(i),2
	entityradius piv2(i),.01
next

positionentity piv2(1), 2,-1,-1
positionentity piv2(2), 4,-1,-1
positionentity piv2(3), 2, 1,-1
positionentity piv2(4), 4, 1,-1
positionentity piv2(5), 2,-1, 1
positionentity piv2(6), 4,-1, 1
positionentity piv2(7), 2, 1, 1
positionentity piv2(8), 4, 1, 1



for i as integer=1 to 8
	actvector piv2(i),0,-.01,0
	actnewtonian piv2(i),.9
	for i2 as integer=i+1 to 8
		if i<>i2 then createconstraint piv2(i),piv2(i2), entitydistance(piv2(i),piv2(i2))
	next
next 






createrigidbody cube2,piv2(1),piv2(2),piv2(3),piv2(5)
fitmesh cube2,0,0,0,1,1,1
updateworld
renderworld

entitytype cube,-3
entitytype cube2,-4

var plane=createplane()':scaleentity plane, 100,.1,100
entitytype plane,5

moveentity plane,0,-4,15
entitycolor plane,255,0,0

collisions 1,5,2,3
collisions 2,5,2,3
collisions 1,4,2,3
collisions 2,3,2,3


var light=createlight()
positionentity light,5,5,5
pointentity light,cube
moveentity camera,0,2,-15
pointentity camera,cube

var s=createcube
positionentity s,3,-3,0
scaleentity s,2,1,2
entitytype s,-5
'turnentity plane,0,0,10

dim key as string
do




	key=inkey
        if key=chr(255)+"H" then moveentity s,0,0,.1
        if key=chr(255)+"P" then moveentity s,0,0,-.1
        if key=chr(255)+"M" then moveentity s,.1,0,0
        if key=chr(255)+"K" then moveentity s,-.1,0,0
	updateworld 1


	renderworld
	sleep 1
	flip
loop until key=chr(27)

Gunslinger
Posts: 107
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

I'm trying to make a builder for a spaceship in game. like a box grid 2d.
like engine and top-cone, fuel tanks, living apartments, trusters.
Where you can place them there every you like. but placing truster out of center of mass will result in problems on lift-off.
So i did not had a lot of time this week.

I do like that open b3d collision detection on complex mesh chapes work fine.
Other hand not a lot of physics in it. so i will work on true-axes for now.

First problem i encounter is linking the model matrix of physics to openb3d models.
i used "lib openb3d" in past. It has the function like this"

Code: Select all

Declare sub TransformEntity(byval _Entity as tEntity ptr, byval as const single)
that i changed to:

Code: Select all

declare sub      TransformEntity(byval _Entity as tEntity ptr, byval pMatrix4x4 as single ptr)
This work perfect for my needs.
seems missing in this openb3d version.
there are other ways, the best is linking the 4x4matrix that has al the data about pos, rot, size

from libopenb3d source, in entity.cpp:

Code: Select all

// added set/get position and orientation from matrix
void Entity::TransformEntity(const float m[16]){
  rotmat.grid[0][0] = m[ 0];rotmat.grid[0][1] = m[ 1];rotmat.grid[0][2] = m[ 2];
  rotmat.grid[1][0] = m[ 4];rotmat.grid[1][1] = m[ 5];rotmat.grid[1][2] = m[ 6];
  rotmat.grid[2][0] = m[ 8];rotmat.grid[2][1] = m[ 9];rotmat.grid[2][2] = m[10];
                 px = m[12];               py = m[13];               pz =-m[14];
  MQ_Update();
}
void Entity::EntityTransform(float m[16]){
  m[ 0]=rotmat.grid[0][0]; m[ 1]=rotmat.grid[0][1]; m[ 2]=rotmat.grid[0][2]; m[ 3]=1.0;
  m[ 4]=rotmat.grid[1][0]; m[ 5]=rotmat.grid[1][1]; m[ 6]=rotmat.grid[1][2]; m[ 7]=1.0;
  m[ 8]=rotmat.grid[2][0]; m[ 9]=rotmat.grid[2][1]; m[10]=rotmat.grid[2][2]; m[11]=1.0;
  m[12]=px;                m[13]=py;                m[14]=-pz;             ; m[15]=1.0;
}
I can't remember why i started using this openb3d version. i think i had problems with LibOpenB3D at some point.
I do like to improve on openb3d and the source code so others can use if in the future.
So i don't like making a other version of openb3d.
Now i realize the problem with maintaining libraries, is there a github version?
Gunslinger
Posts: 107
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

angros47 wrote: Jan 14, 2024 16:40 This example should work a bit better. By the way, if you need a complete physics engine, you would indeed need an external libraries. The functions provided by OpenB3D are mostly for collision detections

Code: Select all

#include "openb3d.bi"




screen 18,  32, , &h10002 

	
Graphics3d 640,480,32,1,1

var camera=createcamera(0)
var cube=createcube()


dim piv(8) as any ptr
for i as integer=1 to 8
	piv(i)=createpivot()
	entitytype piv(i),1
	entityradius piv(i),.01
next

positionentity piv(1),-1,-1,-1
positionentity piv(2), 1,-1,-1
positionentity piv(3),-1, 1,-1
positionentity piv(4), 1, 1,-1
positionentity piv(5),-1,-1, 1
positionentity piv(6), 1,-1, 1
positionentity piv(7),-1, 1, 1
positionentity piv(8), 1, 1, 1



for i as integer=1 to 8
	actvector piv(i),0,-.01,0
	actnewtonian piv(i),.9
	for i2 as integer=i+1 to 8
		if i2<>i then createconstraint piv(i),piv(i2), entitydistance(piv(i),piv(i2))
	next
next 

createrigidbody cube,piv(1),piv(2),piv(3),piv(5)
fitmesh cube,0,0,0,1,1,1





var cube2=createcube()


dim piv2(8) as any ptr
for i as integer=1 to 8
	piv2(i)=createpivot()
	entitytype piv2(i),2
	entityradius piv2(i),.01
next

positionentity piv2(1), 2,-1,-1
positionentity piv2(2), 4,-1,-1
positionentity piv2(3), 2, 1,-1
positionentity piv2(4), 4, 1,-1
positionentity piv2(5), 2,-1, 1
positionentity piv2(6), 4,-1, 1
positionentity piv2(7), 2, 1, 1
positionentity piv2(8), 4, 1, 1



for i as integer=1 to 8
	actvector piv2(i),0,-.01,0
	actnewtonian piv2(i),.9
	for i2 as integer=i+1 to 8
		if i<>i2 then createconstraint piv2(i),piv2(i2), entitydistance(piv2(i),piv2(i2))
	next
next 






createrigidbody cube2,piv2(1),piv2(2),piv2(3),piv2(5)
fitmesh cube2,0,0,0,1,1,1
updateworld
renderworld

entitytype cube,-3
entitytype cube2,-4

var plane=createplane()':scaleentity plane, 100,.1,100
entitytype plane,5

moveentity plane,0,-4,15
entitycolor plane,255,0,0

collisions 1,5,2,3
collisions 2,5,2,3
collisions 1,4,2,3
collisions 2,3,2,3


var light=createlight()
positionentity light,5,5,5
pointentity light,cube
moveentity camera,0,2,-15
pointentity camera,cube

var s=createcube
positionentity s,3,-3,0
scaleentity s,2,1,2
entitytype s,-5
'turnentity plane,0,0,10

dim key as string
do




	key=inkey
        if key=chr(255)+"H" then moveentity s,0,0,.1
        if key=chr(255)+"P" then moveentity s,0,0,-.1
        if key=chr(255)+"M" then moveentity s,.1,0,0
        if key=chr(255)+"K" then moveentity s,-.1,0,0
	updateworld 1


	renderworld
	sleep 1
	flip
loop until key=chr(27)

This version works a lot better, got the rigidbody on separate entity Type is a good idea.
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

About the functions TransformEntity and EntityTransform, they weren't mine, they were added by D.J. Peters in his own version

viewtopic.php?t=27233

My version has the command EntityMatrix, that just returns a pointer to the matrix that is internally used by the entity.

Internally, in OpenB3D, each entity has two matrices: one is rotmat, that is affected only by the rotations relative to the parent entity, and is used for rotational computations. The other is "mat", that is affected by the global rotation, by position, and by scaling, and is the one passed to the renderer.

D.J.Peters's solution accesses the matrix rotmat, then includes the position from the variables px, py, pz. My solution, instead, accesses "mat" directly.

My solution is slightly faster, because there is no need to copy the data, nor to call MQ_Update to recalculate everything. The downside is that if any command like MoveEntity or TurnEntity is applied, the matrix would be reset to what is expected to be. Also, in my solution the matrix is affected by scaling, too (and can be used to resize the entity), and its position and rotation is in absolute coordinates, not related to parent entity (that is irrelevant as long as the entity has no parent)
Gunslinger
Posts: 107
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

I'm not sure what you mean with EntityMatrix. UseEntity function?
no idea how to use that.

But i got distracted bij how many vertex point are created in createspheres() and createcube()
createspheres(16) has 1984 vertices and 1425 are duplicated vertex point at same points
createspheres(32) has 8064 and 5921duplicated
createcube() has 24 and 4 duplicated, need 12?.

zo i wrote a function to clean up the unnecessary points:

Code: Select all

#include "openB3D.bi"

type maskAndNewID
	as long mask =-1 'becose lookupID of old array vertex
	as long newID = -1 'new ID w/h gaps
	as single x,y,z
	as single u,v,w
end type

declare function optimize_mesh_copy( source as any ptr, byref dest as any ptr) as long
declare function optimize_mesh_replace(byref model as any ptr) as long

dim shared as ulong scr_w = 1920
dim shared as ulong scr_h = 1080
screenres scr_w, scr_h, 32, 2, &h10002
screeninfo(scr_w, scr_h) 'read screen result resultion
Graphics3d scr_w,scr_h 'openGL screen hier

dim as any ptr camera = createcamera()
	positionentity camera, 0, 10, -30
	rotateentity camera, -15, 0, 0 'look down a bit
var light=createlight(2)
	turnentity light, -90, 0, 0
	positionentity light, 106, 100, 0
dim as any ptr cube1 = createcube()
	entitycolor cube1, 0, 255, 255
	positionentity cube1, 0, 5, 0
dim as any ptr earth = createsphere(32)
	entitycolor earth, 0, 255, 0
	EntityShininess earth, .5
	positionentity earth, 0, 10, 0


dim as any ptr source = createcube()
'dim as any ptr source = createsphere(32)
	entitycolor source, 255, 0, 255
	scaleentity source, 20, 1.005,20
	EntityShininess source, .5
var texbg = loadtexture("ground_0041_color_1k.jpg", 8)
	entitytexture source, texbg
	
'screen 21
'hideentity source
'optimize_mesh_replace(source) 


function optimize_mesh_replace(byref model as any ptr) as long
	dim as any ptr copy
	dim as long trimed_vertex = optimize_mesh_copy(model, copy)
	freeentity model
	model = CopyEntity(copy)
	freeentity copy
	updatenormals model
	return trimed_vertex
end function 

function optimize_mesh_copy(source as any ptr, byref dest as any ptr) as long
	dest = CopyEntity(source)						'----------copy b3d model here, with all surfaces
	dim as long i
	dim as long counter_removed, counter_newID
	dim as long surfaceCount = CountSurfaces(source) 
	for iSurfaceCount as long = 1 to surfaceCount
		dim as any ptr sourceSurface = GetSurface(source, iSurfaceCount)
		dim as long iVerticesCount = CountVertices(sourceSurface) '0 to i-1 
		dim as maskAndNewID dubbelVertexs(iVerticesCount-1)
		
			'filter dubbel vertexpoint here for each surface and store first one
		for i = 0 to iVerticesCount-1
			if dubbelVertexs(i).mask = -1 then
				dubbelVertexs(i).mask = i
				for n as long = i+1 to iVerticesCount-1
					if dubbelVertexs(n).mask= -1 andalso _
							VertexX(sourceSurface, n)=VertexX(sourceSurface, i) andalso _
							VertexY(sourceSurface, n)=VertexY(sourceSurface, i) andalso _
							VertexZ(sourceSurface, n)=VertexZ(sourceSurface, i) andalso _
							VertexU(sourceSurface, n)=VertexU(sourceSurface, i) andalso _
							VertexV(sourceSurface, n)=VertexV(sourceSurface, i) andalso _
							VertexW(sourceSurface, n)=VertexW(sourceSurface, i) then
						'print "*"; ' a vertex get removed
						dubbelVertexs(n).mask = i
						counter_removed += 1
					end if
				next
				if dubbelVertexs(i).mask = i then
					'print "-" & i,counter_newID 'a vertex marked to keep to new index id
					dubbelVertexs(i).newID = counter_newID
					dubbelVertexs(i).x = VertexX(sourceSurface, i) 'store current vertex pos x,y,z
					dubbelVertexs(i).y = VertexY(sourceSurface, i)
					dubbelVertexs(i).z = VertexZ(sourceSurface, i)
					dubbelVertexs(i).u = VertexU(sourceSurface, i)
					dubbelVertexs(i).v = VertexV(sourceSurface, i)
					dubbelVertexs(i).w = VertexW(sourceSurface, i)
					counter_newID += 1
				end if
			end if
		next
		
		windowtitle "Removed vertex: " & str(counter_removed) & " of the " & iVerticesCount & " = " & str((100/iVerticesCount)*counter_removed) & "%"
		'create new triangle surface with newIDs
		dim as any ptr destSurface = GetSurface(dest, iSurfaceCount)
		iVerticesCount = CountVertices(destSurface) '0 to i-1 
		ClearSurface(destSurface, 1, 1) 'clear the copied surface form triangles en vertex points
		
		for i = 0 to iVerticesCount-1
			if dubbelVertexs(i).newID <> -1 then
				AddVertex(destSurface, dubbelVertexs(i).x, dubbelVertexs(i).y, dubbelVertexs(i).z, dubbelVertexs(i).u, dubbelVertexs(i).v, dubbelVertexs(i).w)
				'VertexTexCoords(destSurface, dubbelVertexs(i).newID,dubbelVertexs(i).u, dubbelVertexs(i).v)
			end if
		next i
		
		'create triangle to new id
		dim as long p1, p2, p3
		dim as long TriangleCount = CountTriangles(sourceSurface)
		for iTriangle as long = 0 to TriangleCount-1
			p1 = dubbelVertexs(dubbelVertexs(TriangleVertex(sourceSurface, iTriangle, 0)).mask).newID
			p2 = dubbelVertexs(dubbelVertexs(TriangleVertex(sourceSurface, iTriangle, 1)).mask).newID
			p3 = dubbelVertexs(dubbelVertexs(TriangleVertex(sourceSurface, iTriangle, 2)).mask).newID
			AddTriangle(destSurface, p1, p2, p3)
		next
	next iSurfaceCount
	
	updatenormals dest
	return counter_removed
end function

wireframe 0
dim as string key
while key<>chr(27)
	key = inkey
	if key = " " then optimize_mesh_replace(source)
	if key = "0" then wireframe 0
	if key = "1" then wireframe 1
	renderworld
	flip
	Sleep 10
wend
Works great on spheres but got problems with cubes and the texture mapping uv coord stuff.
maybe you can help me out. i don't know how the sides are assigned, i just store uv and set it back. think the problem is with iCornerIndex lost that can be get from TriangleVertex?
No idea how to set it or don't know what i'm doing :)

Still think 70%+ of vertex's points not needed is a lot.
I was looking into this because of mesh need to load into static world for physic simulation.
I we can improve this function it's very useful.
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

No, it's the command:

Code: Select all

declare function EntityMatrix cdecl alias "EntityMatrix" (byval ent as any ptr) as single ptr
Forgot to add it to OpenB3D.bi , so consider it an undocumented feature


About the duplicated vertices: in a sphere, they are indeed duplicated, and many of them can be removed (not all, otherwise you might have issues with texture mapping). In a cube, they are NOT duplicated: each face has four vertices, that are not duplicates of the common vertices of other faces: in fact, they have the same x, y, z coordinates, but they have different normals. If you try to use the same vertex for two different faces of a cube, geometry will be rendered correctly, but lighting and shading won't.

On a sphere, that has a curve surface, vertices share the same normals (although some vertices don't share the same UV coordinates, so you can still have issues with texturing), so your function can more or less work, on a cube, for the reason I told you, it cannot work. To make your function work in all cases the whole format of data used by OpenGL would need to be modified.
Gunslinger
Posts: 107
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

Thank you for your information.
my function checks uv if coordinates are different and copies normals from original in same way (maybe..it has bugs)
For spheres it works great now.

I did some testing with 1000 sphere(32) with and without mesh optimize function.
All rolling around with physics on them.

Un-optimized mesh gave me about 830 fps optimized about 1400 in 10 seconds
also the time the function renderworld take is reduced by 40 procent

So all the extra vertices give a real performance difference.
Also noticed entitycopy will remove the hidenstate. bug? i do expect to copy that state of the entity.
angros47
Posts: 2331
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

The main reason CopyEntity doesn't copy the hidden state is that one of the possible uses is "spawning" new entities (it happens, for example, in the particle emitter): in these situation, it's common wanting to keep the original entity hidden, and creating several visible copies of it.

Copying a hidden entity, and wanting the copy to be hidden as well is a much less common case, I'd say

About sphere rendering, there are actually several ways to do it: OpenB3D uses an approach based on latitude and longitude, but it would also be possible to render a sphere using a geodetic sphere approach (for example, starting from a platonic solid and subdivide it until you reach the wanted accuracy)
Each approach has advantages and disadvantages: some solutions are easier to texture, some are rendered faster, some are easier to split into smaller parts (in case you want to animate an explosion, for example). The graphic primitives used in OpenB3D use a simple geometry, that more or less grants acceptable results for all those goals, but is not optimized for any of them. So, if you want spheres that can be rendered faster, and you don't need to texture them, you can use a different algorithm, for example.
badidea
Posts: 2594
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by badidea »

There is something weird going on with multiple camera's and camera fog.
The code below should display 3 rubik's cubes. 2 with fog, 1 without.
What I get is only 2 cubes visible. 1 with fog, 1 without.
Uncommenting line 85 CameraFogMode(cam1, 1) makes the cube on cam3 appear.

Code: Select all

#include "openb3d/openb3d.bi"
'#include "2d2.bi"
#include "fbgfx.bi"

const as integer screen_width = 800, screen_height = 600

'-------------------------------------------------------------------------------

sub object_key_control(obj as any ptr)
	if multikey(FB.SC_UP) then TurnEntity(obj, 0, 0, 2)
	if multikey(FB.SC_DOWN) then TurnEntity(obj, 0, 0,-2)
	if multikey(FB.SC_LEFT) then TurnEntity(obj, 0, 2, 0)
	if multikey(FB.SC_RIGHT) then TurnEntity(obj, 0,-2, 0)
	if multikey(FB.SC_PAGEUP) then TurnEntity(obj, 2, 0, 0)
	if multikey(FB.SC_PAGEDOWN) then TurnEntity(obj, -2, 0, 0)
end sub

'-------------------------------------------------------------------------------

#define RGBA_A(c) (cuint(c) shr 24)
#define RGBA_R(c) ((cuint(c) shr 16) and &hFF)
#define RGBA_G(c) ((cuint(c) shr 8) and &hFF)
#define RGBA_B(c) (cuint(c) and &hFF)

#define rnd_range(low, high) (rnd(1) * ((high) - (low)) + (low))

const as long FACE_FRONT = 0 'red
const as long FACE_BACK = 1 'orange
const as long FACE_LEFT = 2 'green
const as long FACE_RIGHT = 3 'blue
const as long FACE_TOP = 4 'white
const as long FACE_BOTTOM = 5 'yellow

const as ulong CL_RED = &hB80A31 'front
const as ulong CL_ORANGE = &hFF5700 'back
const as ulong CL_GREEN = &h009C46 'left
const as ulong CL_BLUE = &h0044AF 'right
const as ulong CL_WHITE = &hFFFFFF 'top / up
const as ulong CL_YELLOW = &hFFD600 'bottom / down

'-------------------------------------------------------------------------------

type cubie_type
	dim as any ptr entity
	dim as any ptr quad(0 to 5)
	dim as ulong faceColor(0 to 5) '0 for no quad (F,B,L,F,U,D)
end type

dim as cubie_type cubie(-1 to +1, -1 to +1, -1 to +1) 'x,y,z

'set face color, 0 for no face
for x as integer = -1 to +1
	for y as integer = -1 to +1
		for z as integer =-1 to +1
			with cubie(x, y, z)
				if x = -1 then .faceColor(FACE_LEFT) = CL_GREEN
				if x = +1 then .faceColor(FACE_RIGHT) = CL_BLUE
				if y = -1 then .faceColor(FACE_BOTTOM) = CL_YELLOW
				if y = +1 then .faceColor(FACE_TOP) = CL_WHITE
				if z = -1 then .faceColor(FACE_FRONT) = CL_RED
				if z = +1 then .faceColor(FACE_BACK) = CL_ORANGE
			end with
		next
	next
next

'turn 6 quad faces to make a 6-color cube
'order: front, back, left, right, up, down
dim as single quadPitch(0 to 5) = {0, 180,   0,   0, -90, +90}
dim as single quadYaw(0 to 5) =   {0,   0, -90, +90,   0,   0}

' Set video mode 
screencontrol(FB.SET_GL_2D_MODE, FB.OGL_2D_MANUAL_SYNC)
screenres(screen_width, screen_height, 32, 1, FB.GFX_OPENGL or FB.GFX_MULTISAMPLE) 'or GFX_MULTISAMPLE or GFX_ALPHA_PRIMITIVES)
Graphics3d(screen_width, screen_height, 32, 1, 1)

AntiAlias(false)

' Setup light and camera
var light1 = CreateLight(1)
var cam1 = CreateCamera()
CameraViewport(cam1, 0, 0, screen_width\2, screen_height\2) 'bottom-left
PositionEntity(cam1, 0, 0, -5) 'move camera back
'CameraFogMode(cam1, 1)
CameraFogRange(cam1, +1, +5.0)

var cam2 = CreateCamera()
CameraViewport(cam2, screen_width\2, 0, screen_width\2, screen_height\2) 'bottom-right
PositionEntity(cam2, 0, 0, -4) 'move camera back
CameraZoom(cam2, 0.6)
CameraFogRange(cam2, +1, +5.0)
CameraFogMode(cam2, 1)

var cam3 = CreateCamera()
CameraViewport(cam3, 0, screen_height\2, screen_width\2, screen_height\2) 'top-left
PositionEntity(cam3, 0, 0, -8) 'move camera back
CameraZoom(cam3, 0.3)
CameraProjMode(cam3, 2)
CameraRange(cam3, +1, +100.0)
CameraClsColor(cam3, 0.8, 0.5, 0.7)
CameraFogColor(cam3, 0.1, 0.5, 0.9)
CameraFogRange(cam3, +1, +10.0)
CameraFogMode(cam3, 1)

dim as string mystr = ""

'central pivot point (to rotate the entire cube)
var pivot = CreatePivot()

dim as integer count = 0
for x as integer = -1 to +1
	for y as integer = -1 to +1
		for z as integer =-1 to +1
			with cubie(x, y, z)
				'build a small cube from 6 quads  with each side a different color
				.entity = CreateCube(pivot) 'has parent pivot, is parent for quads
				ScaleMesh(.entity, 0.48, 0.48, 0.48)
				EntityColor(.entity, 40, 40, 40)
				MoveEntity(.entity, x, y, z)
				for i as integer = 0 to 5
					dim as ulong c = .faceColor(i)
					if c <> 0 then
						.quad(i) = CreateQuad(.entity) 'child of cubie
						EntityColor(.quad(i), RGBA_R(c), RGBA_G(c), RGBA_B(c))
						PositionMesh(.quad(i), 0, 0, -1)
						ScaleMesh(.quad(i), 0.42, 0.42, 0.50)
						RotateMesh(.quad(i), quadPitch(i), quadYaw(i), 0)
						'EntityParent(quad(i), pivot1)
					end if
				next
			end with
			count += 1
			'if count = 3 then exit for,for,for
		next
	next
next

'EntityParent(cubie, pivot2)
'PositionMesh(cubie, 2, 1, 3)
'TurnEntity(pivot, 20, 30, 0)
'RotateEntity(cubie, 20, 30, 0)

'wireframe(1)

'Make freebasic print work on 3d screen (2d2.bi)
'dim as font2d f2d

'-------------------------------------------------------------------------------

randomize timer
dim as single dPitch, dYaw, dRoll
dim as double tUpdate = timer + 0.1
while not multikey(FB.SC_ESCAPE)
	object_key_control(pivot) ' control cube1 with arrow keys
	TurnEntity(pivot, dPitch, dYaw, dRoll)
	UpdateWorld()
	RenderWorld()
	'f2d.print(10, 10, "Hello Cube! " & mystr)
	flip
	sleep 1
	if timer > tUpdate then
		tUpdate = timer + 1 'change something again in 3 seconds
		dPitch = rnd_range(-1, +1)
		dYaw = rnd_range(-1, +1)
		dRoll = rnd_range(-1, +1)
	end if
wend
sleep
end
Post Reply