I spent a few mins making a side-by-side comparison using welded and non-welded spheres in this little demo. Notice how the welded vertices accept light in a different manner. What do you make of that?
sync on
sync rate 60
autocam off
position camera 0,0,-4
make object sphere 1, 2.0
rotate object 1, 45.0, 0.0, 45.0
fix object pivot 1
set object wireframe 1,1
position object 1,-1.5,0,0
make object sphere 2, 2.0
rotate object 2, 45.0, 0.0, 45.0
fix object pivot 2
set object wireframe 2,1
position object 2,1.5,0,0
type Vertex_t
x as float
y as float
z as float
nx as float
ny as float
nz as float
u as float
v as float
Diffuse as dword
OriginalPosition as integer
UsageCount as integer
endtype
type VertexInfo_t
Vertex as Vertex_t
OriginalPosition as integer
Matches as integer
UsageCount as integer
endtype
global dim Vertex() as VertexInfo_t
global dim Index() as integer
WeldLimbVertices(1, 0)
set object cull 1, 0
set object cull 2, 0
repeat
if spacekey()
StopRotations=1-abs(StopRotations)
wait 300
endif
lock vertexdata for limb 1, 0
set cursor 0, 0
print "Welded vertex count() = "; get vertexdata vertex count()
print "Welded index count() = "; get vertexdata index count()
unlock vertexdata
lock vertexdata for limb 2, 0
set cursor 320, 0
print "Non-Welded vertex count() = "; get vertexdata vertex count()
set cursor 320, 10
print "Non-Welded index count() = "; get vertexdata index count()
unlock vertexdata
` for i = 0 to array count( Vertex() )
` print i; " - "; Vertex(i).UsageCount; " - "; Vertex(i).Matches; " - "; Vertex(i).Vertex.x; "/"; Vertex(i).Vertex.y; "/"; Vertex(i).Vertex.z
` next
if StopRotations=0
rotate object 1, 0.0, wrapvalue( object angle y(1) + 1.0 ), 0.0
rotate object 2, 0.0, -object angle y(1), 0.0
endif
sync
until returnkey()
end
function WeldLimbVertices(Object as integer, Limb as integer)
make object from limb 9999, Object, Limb
make mesh from object 9999, 9999
delete object 9999
change mesh Object, Limb, 9999
delete mesh 9999
local V as Vertex_t
local VI as VertexInfo_t
lock vertexdata for limb Object, Limb
` Create/recreate arrays needed for manipulation
undim Vertex()
global dim Vertex( get vertexdata vertex count() - 1 ) as VertexInfo_t
undim Index()
global dim Index( get vertexdata index count() - 1 ) as integer
` Copy all vertex data into an array
for i = 0 to array count( Vertex() )
V.x = get vertexdata position x(i)
V.y = get vertexdata position y(i)
V.z = get vertexdata position z(i)
V.nx = get vertexdata normals x(i)
V.ny = get vertexdata normals y(i)
V.nz = get vertexdata normals z(i)
V.u = get vertexdata u(i)
V.v = get vertexdata v(i)
V.Diffuse = get vertexdata diffuse(i)
Vertex(i).Vertex = V
Vertex(i).OriginalPosition = i
Vertex(i).Matches = i
Vertex(i).UsageCount = 0
next
` Copy all index data into an array
for i = 0 to array count( Index() )
Index(i) = get indexdata(i)
inc Vertex( Index(i) ).UsageCount
next
` Look for matching vertices
for i = 1 to array count( Vertex() )
for j = 0 to i - 1
if CheckMatchingVertex(i, j) = 1
` Update the matching vertex
Vertex(j).Vertex.nx = Vertex(j).Vertex.nx + ( Vertex(i).Vertex.nx * Vertex(i).UsageCount )
Vertex(j).Vertex.ny = Vertex(j).Vertex.ny + ( Vertex(i).Vertex.ny * Vertex(i).UsageCount )
Vertex(j).Vertex.nz = Vertex(j).Vertex.nz + ( Vertex(i).Vertex.nz * Vertex(i).UsageCount )
Vertex(j).UsageCount = Vertex(j).UsageCount + Vertex(i).UsageCount
` Update this duplicate vertex
Vertex(i).UsageCount = 0
Vertex(i).Matches = j
` Skip on to the next vertex
exit
endif
next
next
` Divide the normals by the usage count (effectively, averaging the normals)
for i = 0 to array count( Vertex() )
if Vertex(i).UsageCount > 0
Vertex(i).Vertex.nx = Vertex(i).Vertex.nx + Vertex(i).UsageCount
Vertex(i).Vertex.ny = Vertex(i).Vertex.ny + Vertex(i).UsageCount
Vertex(i).Vertex.nz = Vertex(i).Vertex.nz + Vertex(i).UsageCount
endif
next
` Sort the vertices so unused ones are at the end
repeat
Swap = 0
for i = 1 to array count( Vertex() )
if Vertex(i-1).UsageCount < Vertex(i).UsageCount
Swap = 1
VI = Vertex(i-1)
Vertex(i-1) = Vertex(i)
Vertex(i) = VI
endif
next
until Swap = 0
` Update the indices so that duplicates point at the original
for i = 0 to array count( Index() )
Index(i) = FindVertexFromIndex( Index(i) )
next
` Update the object index data
for i = 0 to array count( Index() )
set indexdata i, Index(i)
next
` Update the object vertex data
i = 0
while Vertex(i).UsageCount > 0
set vertexdata position i, Vertex(i).Vertex.x, Vertex(i).Vertex.y, Vertex(i).Vertex.z
set vertexdata normals i, Vertex(i).Vertex.nx, Vertex(i).Vertex.ny, Vertex(i).Vertex.nz
set vertexdata uv i, Vertex(i).Vertex.u, Vertex(i).Vertex.v
set vertexdata diffuse i, Vertex(i).Vertex.Diffuse
inc i
endwhile
delete mesh from vertexdata i, get vertexdata vertex count(), get vertexdata index count(), get vertexdata index count()
unlock vertexdata
endfunction
function CheckMatchingVertex(i as integer, j as integer)
if Vertex(i).Vertex.x <> Vertex(j).Vertex.x then exitfunction 0
if Vertex(i).Vertex.y <> Vertex(j).Vertex.y then exitfunction 0
if Vertex(i).Vertex.z <> Vertex(j).Vertex.z then exitfunction 0
endfunction 1
function FindVertexFromIndex(Ind as integer)
for i = 0 to array count( Vertex() )
if Vertex(i).OriginalPosition = Ind
if Vertex(i).OriginalPosition = Vertex(i).Matches then exitfunction i
exitfunction FindVertexFromIndex( Vertex(i).Matches )
endif
next
endfunction -1
Visit the Wip!
