How to know if a vertex need to be duplicated or n

Community Forums/General Help/How to know if a vertex need to be duplicated or n

RemiD(Posted 2013) [#1]
Hello,

When i create a cube in Blitz3d, some vertices are duplicated so that some triangles can have their own vertices (not shared with others triangles), and this allows to have another lighting, a bit like flat shaded lighting but only on some faces.

Now let's say that i have a mesh with all its vertices being shared by several triangles and that i want to have some triangles have their own vertices (not shared with others triangles) so that the lighting is more realistic. How do i know which vertices to duplicate or not ?

I have thought to do this :
->calculate the normal of each triangle
->choose a triangle
->choose a vertex of this triangle
->if this vertex is shared with another triangle
->calculate if the angle between the normal of this triangle and the normal of the other triangle allows to receive lighting from the same direction or not (0 to 180 or -180 to 0)
->if yes
keep only one vertex for the 2 triangles
->if no
create a vertex for each triangle

If you have some experience with this, can you please explain how i can manage to do this ?

The goal is to be able to have a better lighting on mesh which has been welded, that is a mesh where each triangle share its vertices with others triangles.

To illustrate what i mean :

I want a mesh like the one at left to be recreated so that it will be lighted like the one at right.

But with more complex meshes.

Any suggestions will be appreciated.

Thanks,


Yasha(Posted 2013) [#2]
There's a code archive entry that will do pretty much what you need, already written courtesy of BIG BUG: UpdateNormalsAngle

You can specify the threshold angle below which faces will share vertices, and it will take care of the details. Handy stuff.


RemiD(Posted 2013) [#3]
Yasha>>i have already seen this code but i thought that it only calculated new vertices normals, not create new vertices.

I will study it. Thanks.


Yasha(Posted 2013) [#4]
I could be misremembering what it does, but in any case if necessary you can always supplement it with two other steps:

1) Do a full unweld of the mesh
2) UpdateNormalsAngle
3) Do a weld only of those vertices that have identical normals as well as position

It's a bit roundabout, but you'll get the same end result eventually.


Kryzon(Posted 2013) [#5]
I coded a system like this for my B3D exporter for 3DS Max.
In my case, I was using the SMOOTHING GROUPS as reference to know which vertices to BREAK or to WELD, but in your case you're using as reference the triangles that are COPLANAR.

The logic steps you described are somewhat similar, but I preferred to work in a vertex-level instead of triangle. That is, I went through all vertices, identified which triangles it belonged to, THEN checked the normal of these triangles and for any triangles with a different normal, I duplicated the vertex and assigned this duplicate to the triangle.

It's imperative that you leave the original mesh alone, and instead work on an ABSTRACT mesh.
That is, recreate an exact copy of the original mesh but store the geometry information in user-types:
Type TempVertex
	Field index	

	Field x#, y#, z#
	Field #u, #v
	field #nx, #ny, #nz
End Type

Type TempTriangle
	Field index1, index2, index3

	Field vertex1.TempVertex
	Field vertex2.TempVertex
	Field vertex3.TempVertex	
End Type
Because this allows you to break or weld vertices more easily than if you kept using Blitz3D surface commands all the time. This way, to "weld" vertices you simply have to assign the same vertex instance to several triangles.

Only at the end is that you use this processed abstract mesh to create an actual Blitz3D mesh with surface and everything.


RemiD(Posted 2013) [#6]
Ok after some tests, it seems that the code by BigBug doesn't produce what i want achieve, i will try to code my own routine.

Thanks for the advices,


Stevie G(Posted 2013) [#7]
In my opinion, the best way to do this is ...

1. Weld the mesh to remove any unwelded triangles.
2. Unweld the mesh to ensure all triangles are unwelded
3. Calculate and set all the normals based on the vertices of each triangle.

Example code and functions below ...

Note that I welded entity TEST1 and used updatenormals on it to show the dodgy lighting on a welded version.




RemiD(Posted 2013) [#8]
Stevie G>>Thanks, your example shows what i call a flat shaded mesh, where each triangle has its own vertices, what i want is a mix between this and a progressive shaded, where some triangles share some vertices.

I have already coded a routine similar to yours, i like the render, i may use this afterall.

Let's say that i want to recreate a rigged, skinned, animated mesh, (.b3d), the only way is to write the .b3d file or is there any other way ?

Thanks,


BIG BUG(Posted 2013) [#9]
You're right, there is no API for bone access, so writing a .b3d file is your only option.


Yasha(Posted 2013) [#10]
You can dynamically add bones to a mesh at runtime with this: http://www.blitzbasic.com/codearcs/codearcs.php?code=2485

However, the method is very B3D-version-dependent, hasn't been properly tested, etc. etc. I make no guarantee that it actually works. Writing a B3D file is slower but guaranteed to work.


RemiD(Posted 2013) [#11]
Ok, thanks for the infos. :)