@BatVink,
I "accumulate" the curent limb offset in a UDT for each object and as I continue to add limbs, I increment this accumulated limb offset. Although I've never used this for terrain pieces, it should work the same.
In 3DWS, you just have to make sure you give a classname to each brush, and make sure that all the brushes that you want to be considered as 1 "object" in DBPro have the
same classname. So, for example, if I have an arch made up of 36 brushes, I need to name them all "sewer_entrance_arch" or something like that so the code sees that I want to see them all as 1 object.
Hmmm, 1 block of code is worth 1000 words, maybe this will explain better (take a look at the propsLoad() function):
(uses Sparky's and several of Iam's Matrix Utils - won't run as-is since the dependent pieces aren't here, but should give you an idea)
REM props.dba
REM Dependencies : log.dba, images.dba
REM USE:
REM gosub propsSetup before your main game loop
REM place propsCull() in your main game loop
REM to manually load a DBO file, use propsLoad("filename.dbo",LOGFILENUMBER,0,0,0)
REM and propsSetStats(objectNumber)
REM to see a demo, edit the propName$ variable in propsDemo()
REM and call it before your main game loop
propsSetup:
type propsType
REM Array Index is DBPRO Object ID
volume as float
minsize as float
avgsize as float
maxsize as float
posX as float
posY as float
posZ as float
fullvisible as boolean
classname as string
objecttype as string
lkgox as float
lkgoy as float
lkgoz as float
distancecull as boolean
endtype
dim props() as propsType
add to queue props() `This is important don't remove, it creates a "null" prop
REM PROP CONSTANTS
#constant PROPSCONVERTTODBO 0
#constant PROPSDIRECTORY "media/"
#constant PROPSLOADDEBUG 1
#constant PROPSCONVERTLIMBS 1
#constant PROPSCULLFADESTART 1024.0
#constant PROPSCULLEXCLUDE 1280.0
#constant PROPSCULLBASESIZE 16.0
#constant PROPSCULLINTERVAL 25
#constant PROPSGROUPLIMBS 1
#constant PROPVECTOR 2
vec = make vector3(PROPVECTOR)
global propsCullObjectIndex as integer = 1
global propsClassName$ = ""
global propsLimbLoader = 0
propsLimbLoader = propsCreate()
props(propsLimbLoader).classname = "complexObject"
props(propsLimbLoader).objecttype = "system"
props(propsLimbLoader).fullvisible = 0
global propsCullTimer as integer = 0
return
function propsCreate()
add to queue props()
propID = array count(props())
props(propID).classname = "INVALID"
props(propID).objecttype = "INVALID"
props(propID).fullvisible = 0
props(propID).distancecull = 0
endfunction propID
function propsCull()
if object exist (propsCullObjectIndex)
if props(propsCullObjectIndex).distancecull = 1
Set Vector3 PROPVECTOR,(props(propsCullObjectIndex).posX-object position x(playerActiveID)),(props(propsCullObjectIndex).posY-object position y(playerActiveID)),(props(propsCullObjectIndex).posZ-object position z(playerActiveID))
dist#=Length Vector3(PROPVECTOR)
REM ARTIFICIALLY GROW OR SHRINK DIST# BASED ON THE minSIZE OF OBJECT COMPARTED TO PROPSCULLBASESIZE
REM SUCH THAT SMALLER OBJECT FADE FASTER AND LARGER OBJECTS FADE SLOWER
objectSizeFactor# = PROPSCULLBASESIZE / props(propsCullObjectIndex).minsize
if objectSizeFactor# => 1.0
REM OBJECT IS SMALLER THAN THE PROPSCULLBASESIZE - Use Fast Fade Rate
dist# = dist# * (objectSizeFactor# * 2.0)
else
REM OBJECT IS LARGER THAN THE PROPSCULLBASESIZE - Use Slow Fade Rate
dist# = dist# + (objectSizeFactor# * 0.5)
endif
if dist# <= PROPSCULLEXCLUDE
if object visible(propsCullObjectIndex) = 0
show object propsCullObjectIndex
exclude object off propsCullObjectIndex
SC_setObjectCollisionOn propsCullObjectIndex
endif
endif
if dist# < PROPSCULLFADESTART
if props(propsCullObjectIndex).fullvisible = 0
color object propsCullObjectIndex, (rgb(255,255,255) && 0xffffff) + (255 << 24)
props(propsCullObjectIndex).fullvisible = 1
endif
endif
if dist# => PROPSCULLFADESTART and dist# < PROPSCULLEXCLUDE
i = 255 - int(floor((dist# - PROPSCULLFADESTART)))
color object propsCullObjectIndex, (rgb(255,255,255) && 0xffffff) + (i << 24)
props(propsCullObjectIndex).fullvisible = 0
endif
if dist# > PROPSCULLEXCLUDE
if object visible(propsCullObjectIndex) = 1
hide object propsCullObjectIndex
exclude object on propsCullObjectIndex
SC_setObjectCollisionOff propsCullObjectIndex
endif
endif
endif `if distancecull = 1
endif `if object exist
inc propsCullObjectIndex
if propsCullObjectIndex > (array count(props()))
propsCullObjectIndex = 1
endif
endfunction
function propsDemo()
rem MAKE A SIMPLE FLOOR
temp = propsCreate()
props(temp).objectType = "box"
props(temp).classname = "system"
props(temp).fullvisible = 1
make object box temp, 4000, 2, 4000
position object temp, 0,-20,0
color object temp, rgb(192,192,192)
SC_setupObject temp, 1, 2
propSpacing = 768
propName$="City_Block2_solids"
propsLoad(propName$,LOGFILENUMBER,0,0,0)
propName$="City_Block2_details"
propsLoad(propName$,LOGFILENUMBER,0,0,0)
propName$="City_Block2_transparent"
propsLoad(propName$,LOGFILENUMBER,0,0,0)
for i = array count(props()) to 1 step -1
propsSetStats(i)
next i
endfunction
function propsFindClass(cn$)
ctr=0
true=1
ac = array count(props(0))
while ctr < ac and true <> 0
inc ctr
if props(ctr).classname = cn$
true=0
endif
endwhile
if ctr = ac
ctr=0
endif
endfunction ctr
function propsFindLimbLink(pid)
ctr=-1
true=0
ac = 65535
while ctr <= ac and true <> 1
inc ctr
if not limb exist (pid,ctr)
true = 1
endif
endwhile
endfunction ctr
function propsLoad(filebase$,logID,x,y,z)
REM ***********************
REM LOAD AND CONVERT OBJECT
REM ***********************
filenameX$ = PROPSDIRECTORY + filebase$ + ".x"
filenameDBO$ = PROPSDIRECTORY + filebase$ + ".dbo"
fileExt$=""
propsTempLoader = propsCreate()
props(propsTempLoader).classname = "complexObject"
props(propsTempLoader).objecttype = "collision"
props(propsTempLoader).fullvisible = 0
if file exist(filenameX$)
if not file exist (filenameDBO$)
REM XFILE EXISTS BUT DBO DOES NOT EXIST - CONVERT IF CONVERT FLAG SET
if (PROPSCONVERTTODBO = 1)
REM CONVERSION IS DESIRED, DO THE CONVERSION
msg$ = "PROPSLOAD,OK,CONVERSIONREQUESTED,"+filenameX$+","+filenameDBO$
logWrite(msg$)
load object filenameX$,propsTempLoader
save object filenameDBO$, propsTempLoader
delete object propsTempLoader
load object filenameDBO$,propsTempLoader
fileExt$=".dbo"
else
REM CONVERSION IS NOT DESIRED, JUST LOAD XFILE
msg$ = "PROPSLOAD,OK,DONOTCONVERT,"+filenameX$+","+filenameDBO$
logWrite(msg$)
load object filenameX$,propsTempLoader
fileExt$=".x"
endif
else
REM DBO ALREADY EXISTS, JUST LOAD DBO FILE
msg$ = "PROPSLOAD,OK,DBOLOADEDINSTEADOFXFILE,"+filenameX$+","+filenameDBO$
logWrite(msg$)
load object filenameDBO$, propsTempLoader
fileExt$=".dbo"
endif
else
REM XFILE DOES NOT EXIST, TRY DBO
if file exist(filenameDBO$)
msg$ = "PROPSLOAD,WARNING,NOXFILELOADEDDBO,"+filenameX$+","+filenameDBO$
logWrite(msg$)
load object filenameDBO$, propsTempLoader,3
fileExt$=".dbo"
else
REM NEITHER XFILE NOR DBO FILE EXIST, LOG A ERROR
msg$ = "PROPSLOAD,ERROR,NOXFILENODBOFILE,"+filenameX$+","+filenameDBO$
logWrite(msg$)
fileExt$=".ERROR"
endiF
endif
position object propsTempLoader, x, y, z
if instr(filebase$,"transparent")
Set Object Transparency propsTempLoader, 4
endif
sc_setupComplexObject propsTempLoader,1,2
REM *************
REM PROCESS LIMBS
REM *************
IF PROPSGROUPLIMBS = 1
hide object propsTempLoader
exclude object on propsTempLoader
limbNum = 0
while limb exist(propsTempLoader, limbNum)
properties$=limb name$(propsTempLoader,limbNum)
objecttype$=lower$(KeyValue$(properties$,"objecttype",""))
classname$=lower$(KeyValue$(properties$,"classname",""))
lx# = limb position x(propsTempLoader,limbNum)
ly# = limb position y(propsTempLoader,limbNum)
lz# = limb position z(propsTempLoader,limbNum)
tex0 = 0
tex1 = 0
if limb texture name(propsTempLoader,limbNum,0) <> ""
tex0 = imagesFindFileName((PROPSDIRECTORY + limb texture name(propsTempLoader,limbNum,0)),0)
endif
if limb texture name(propsTempLoader,limbNum,1) <> ""
tex1 = imagesFindFileName((PROPSDIRECTORY + limb texture name(propsTempLoader,limbNum,1)),0)
endif
pid = 0
select objecttype$
case "brush"
propsClassName$ = str$(propsTempLoader) + "_" + classname$
endcase `brush
case "face"
pid = propsFindClass(propsClassName$) `prop id
if pid = 0
REM CLASS DOES NOT YET EXIST AS AN OBJECT - MAKE NEW OBJECT
pid=propsCreate()
make object from limb pid,propsTempLoader,limbNum
position object pid,lx#,ly#,lz#
props(pid).posX = object position x(pid)
props(pid).posY = object position y(pid)
props(pid).posZ = object position z(pid)
props(pid).objecttype = objecttype$
props(pid).classname = propsClassName$
props(pid).distancecull = 1
props(pid).lkgox = lx#
props(pid).lkgoy = ly#
props(pid).lkgoz = lz#
else
REM CLASS ALREADY EXISTS AS AN OBJECT (object pid) - ADD THIS LIMB TO IT
if object exist(propsLimbLoader)
delete object propsLimbLoader
endif
if mesh exist (1)
delete mesh 1
endif
if object exist(propsTempLoader) = 0
msg$="Object does not exist: " + str$(propsTempLoader) + ", classname = " + propsClassName$
show message msg$
endif
make object from limb propsLimbLoader,propsTempLoader,limbNum,1
position object propsLimbLoader,lx#,ly#,lz#
make mesh from object 1,propsLimbLoader
addLimbAt = propsFindLimbLink(pid)
add limb pid, addLimbAt, 1
link limb pid, addLimbAt-1, addLimbAt
offset limb pid, addLimbAt, lx#-(props(pid).lkgox), ly#-(props(pid).lkgoy), lz#-(props(pid).lkgoz)
if tex0 <> 0
texture limb pid, addLimbAt, 0, tex0
endif
if tex1 <> 0
texture limb pid, addLimbAt, 1, tex1
endif
props(pid).lkgox = limb position x(propsTempLoader,limbNum)
props(pid).lkgoy = limb position y(propsTempLoader,limbNum)
props(pid).lkgoz = limb position z(propsTempLoader,limbNum)
endif
endcase `face
case "bspwalls"
pid=propsCreate()
make object from limb pid,propsTempLoader,limbNum
position object pid,lx#,ly#,lz#
props(pid).classname = propsClassName$
if pid > propsEnd
propsEnd = pid
endif
endcase `bspwalls
endselect `objectype
inc limbNum
endwhile
ENDIF `PROPSGROUPLIMBS = 1
if object exist(propsLimbLoader)
delete object propsLimbLoader
endif
if mesh exist (1)
delete mesh 1
endif
endfunction
function propsSetStats(i as integer)
if object exist (i)
if props(i).distancecull = 1
set object transparency i,6
endif
REM VOLUME, MAXSIZE, AND AVGSIZE CAN BE CALCULATED NORMALLY,
REM WITH A SIMPLE CORRECTION TO CHANGE SIZE 0.0 DIMENSIONS TO 1.0
a# = max(object size x(i,1),1.0)
b# = max(object size y(i,1),1.0)
c# = max(object size z(i,1),1.0)
props(i).volume = a# * b# * c#
props(i).avgsize = (a# + b# + c#) / 3.0
d# = max(a#, b#)
props(i).maxsize = max(d#, c#)
REM FOR MINIMUM SIZE, WE WANT TO CORRECT OBJECTS WITH A SIZE 0.0 DIMENSION
REM AND ARTIFICALLY MAKE THEM A MORE REASONABLE SIZE
if object size x(i,1) = 0
a# = min(object size y(i,1),object size z(i,1))
else
a# = object size x(i,1)
endif
if object size y(i,1) = 0
b# = min(object size x(i,1),object size z(i,1))
else
b# = object size y(i,1)
endif
if object size z(i,1) = 0
c# = min(object size x(i,1),object size y(i,1))
else
c# = object size z(i,1)
endif
d# = min(a#, b#)
props(i).minsize = min(d#, c#)
endif
endfunction
function KeyValue$(properties$,findname$,defaultvalue$)
findname$=lower$(findname$)
repeat
p=instr(properties$,chr$(13)+chr$(10))
if p>0
keypair$=left$(properties$,p-1)
properties$=right$(properties$,len(properties$)-p-1)
else
keypair$=properties$
properties$=""
endif
p=instr(keypair$,"=")
if p=0
exitfunction ""
else
name$=left$(keypair$,p-1)
value$=right$(keypair$,len(keypair$)-p)
if lower$(name$)=findname$ then exitfunction value$
endif
until properties$=""
endfunction defaultvalue$
function propsLogStatus()
logOpen()
propID = 1
limbNum = 0
while object exist (propID)
while limb exist (propID,limbNum)
msg$ = "PROPSLOGSTATUS,DEBUG,LIMBDATA,"+str$(propID)+","+str$(limbNum)+","
msg$ = msg$ + LIMB NAME$(propID, limbNum)+","
msg$ = msg$ + LIMB TEXTURE NAME(propID, limbNum,0)+","
msg$ = msg$ + LIMB TEXTURE NAME(propID, limbNum,1)+","
msg$ = msg$ + "Object Position: " + str$(object position x(propID)) + ","
msg$ = msg$ + str$(object position y(propID)) + ","
msg$ = msg$ + str$(object position z(propID)) + ","
msg$ = msg$ + "Limb Position: " + str$(limb position x(propID, limbNum)) + ","
msg$ = msg$ + str$(limb position y(propID, limbNum)) + ","
msg$ = msg$ + str$(limb position z(propID, limbNum)) + ","
msg$ = msg$ + "Limb Offset: " + str$(limb offset x(propID, limbNum)) + ","
msg$ = msg$ + str$(limb offset y(propID, limbNum)) + ","
msg$ = msg$ + str$(limb offset z(propID, limbNum))
logWrite(msg$)
inc limbNum
endwhile
limbNum = 0
inc propID
endwhile
logClose()
endfunction