sorry for X post, but I need some advanced help!

Blitz3D Forums/Blitz3D Programming/sorry for X post, but I need some advanced help!

StOrM3(Posted 2004) [#1]
Please see the topic = Working with Collisions and Meshes created by me in the Newbies forum, and help if you can, my email for responses and changes / code samples / fixes can be sent to storm3@....

thank you,

Ken


sswift(Posted 2004) [#2]
You know that's a lot of code to go through. It would be a lot easier to find your problem if you formatted it better, and simplified it.

For example, look what I have done to your function to load your meshes...

.FruitData
Data "Cherry",     "cherry.b3d"
Data "Strawberry", "strawberry.b3d"
Data "Orange",     "orange.b3d"
Data "Pear",       "pear.b3d"
Data "Apple",      "apple.b3d"
Data "Pineapple",  "pineapple.b3d"
Data "Banana",     "banana.b3d"

Restore FruitData

For count = 1 To 7

	Read Name$
	Read Filename$
	
	fruitarray(count)\fmodel = LoadMesh("../media/" + FileName$) ;Load initial model from b3d file.

	meshx# = EntityX(fruitarray(count)\fmodel, True) ;get initial x,y,z coords for model.
	meshy# = EntityY(fruitarray(count)\fmodel, True)
	meshz# = EntityZ(fruitarray(count)\fmodel, True)

	RotateMesh(fruitarray(count)\fmodel, 60, 30, 0) ; Rotate the mesh after loading it.
	;FitMesh(fruitarray(count)\fmodel, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True) ;stuff it in a box
	ScaleMesh(fruitarray(count)\fmodel, 3, 3, 3)

	sizex# = MeshWidth(fruitarray(count)\fmodel)
	sizey# = MeshHeight(fruitarray(count)\fmodel)
	sizez# = MeshDepth(fruitarray(count)\fmodel)

	avg# = sizex# + sizey# + sizez# / 3

	EntityRadius(fruitarray(count)\fmodel,avg# + 10.0) ; setting the entities collision radius to 20.
	
	fruitarray(count%)\number = count
	fruitarray(count%)\name$ = Name$

	NameEntity fruitarray(count)\fmodel, Name$ ;entityname for use in collision and points etc..

Next	



Note how much shorter it is. And how much easier to read. Storing the data in data staements allowed me to avoid copying the same code seven times.

Also, I removed all the % symboles from the integers. They're uneccessary because Blitz assumes any variable initially created without a symbol is an integer. Makes the code easier to read. Just make sure you always use a symbol on the other data types and you'll be all set.

I psoted that code by putting a square bracket, and then the word "code" followed by another square bracket, with the same at the end, but "/code" between the brackets instead. That preserves the formatting.

I'm hoping you use indentation and it just got lost because you posted the code as plain text. Formatting is important for code readability.

Now, none of this is going to solve your problem, but it will make it easier for you, and others to find it.

I noticed you mentioned that your objects were falling through the floor, when you used scaleentity.

Well, you are using scalemesh here, but if you were using scalenetity, then using meshwidth to get the XY and Z scale will not take into account the new scale. You will need to also use TFormPoint like so:

Where Mxyz is the mesh scale on each axis,
and Mesh is the mesh whose scale you are calculating.

TFormPoint Mx#, My#, Mz#, 0, Mesh
Mx# = TFormedX#()
My# = TFormedY#()
Mz# = TFormedZ#()

You must do this AFTER the entityscale.


Of course this assumes that entity collision radiuses do not AUTOMATICALLY take into account the scale changes of an entity. WIthout looking at the docs or testing I could not tell you.

Next up on the problems I notice now that the code is cleaned up are the way you're calculating the radius from the meshwidth/height/depth.

Let's assume that we have a cube that is 1 unit wide.
Meshwidth will return 1.
The cube's radius however is not 1. From the middle to the side, it is only 0.5 wide. So right there you have a problem.

So first, divide meshwidth/height/depth by 2.

Next thing to take int account is that the corner of the cube is not 0.5 from the center. It is farther away. It is in fact 1.732 away from the center.

So if you want to fully encompass any entity regardless of it's shape with a radius that fits it, you'll want to pretend it's a cube.

So what to do with the meshwidth,height,depth to fix this problem?

The way I know the distance to the corner is via the distance equation. D = Sqr(X^2 + Y^2 + Z^2).

To make a long story short, one corner of the cube/rectangle is at MeshWidth/2, MeshHeight/2, MeshDepth/2.

Knowing this, and assuming you have placed these three values in Mxyz, you can calculate the radius that fits this rectangle smallest like so:

Radius# = Sqr(Mx#*Mx# + My#*My# + Mz#*Mz#)


One last thing of note. Even if you don't mind some error, your original equation was messed up.

Here is your original:
avg# = sizex# + sizey# + sizez# / 3

With this equation, you divide size# by 3, and then add X and Y. What you meant to do was this:

avg# = (sizex# + sizey# + sizez#) / 3.0

That gives the proper order of operations of adding all three values before dividing.

But as I said, that is not the proper equation to use.


Anyhow I hope some this helps you find your bug.


StOrM3(Posted 2004) [#3]
Swift you are awesome! I did not know about using the data statements. Also, yea, I am not good at math, and the code I posted was messed up by me posting it in text format. I have tried using scalemesh and scaleentity, when using fitmesh the fruit looks right, and stops on collision with the level, but there is a ghost item on the level in the center for some reason, anyways I think I'm going to use coldet to make it easier to understand and better collision detection.