Join also our Discord channel! Click here.

[HELP] Where to start on creating a model/animation viewer

Post questions about game models here, or help out others!
User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

[HELP] Where to start on creating a model/animation viewer

Post by askB » Wed Mar 08, 2017 12:47 am

I am really interested in creating a viewer for the models/animation for Rainbow Six Rouge Spear. What coding language would you guys recommend I start with?
Last edited by askB on Thu Mar 09, 2017 2:03 am, edited 1 time in total.

User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 3189
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 875 times
Been thanked: 1753 times

Re: [HELP] Where to start on creating a model/animation view

Post by shakotay2 » Wed Mar 08, 2017 7:42 am

Did you ever code?
If 'yes' which programming language did you use?
If 'no' it's a bad idea to start with a modelviewer. Check some basic tutorials instead about Java for beginners,
C# (or 'C'). You could also look for python (not recommended, imho :D ).

Coding a modelviewer from scratch doesn't make much sense, imho, since there's dozens of sources.

Take a look at hex2obj (view link in my sig) which makes use of mesh_viewer.exe which is a simple one but fulfills my needs. (hex2obj creates an obj file, then calls the viewer with the *.obj as a parameter.)
Bigchillghost, Reverse Engineering a Game Model: viewtopic.php?f=29&t=17889
extracting simple models: viewtopic.php?f=29&t=10894
Make_H2O-ForzaHor3-jm9.zip
"You quoted the whole thing, what a mess."

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Thu Mar 09, 2017 4:11 am

I am familiar with both coding languages. Also, after viewing your suggestion I still do not believe that HextoObj will work; My case is a bit more complex. I have types of files. CRP, SKL, and DAM.

CRP-Model
SKL-Rig
DAM-animation

I want to create an application that will allow the user to view a model, and play its animations by injecting the .DAM into a .SKL file. That is wh I want to design it from scratch.

User avatar
Acewell
VIP member
VIP member
Posts: 1329
Joined: Wed Nov 05, 2008 12:16 pm
Has thanked: 2683 times
Been thanked: 831 times

Re: [HELP] Where to start on creating a model/animation view

Post by Acewell » Thu Mar 09, 2017 4:20 am

Noesis can be your model/animation viewer, you just need to feed it your data in C++(?) or Python :D

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Thu Mar 09, 2017 4:59 am

So if wanted to create a script to read the model files and inject a .DAM(animation) into the .SKL(rig/model) of the model, I would just have to create a simple script from c++ to run off of noesis? The models themselves are really old so I imagine it wouldn't require a ton of work to create such a code.

User avatar
Acewell
VIP member
VIP member
Posts: 1329
Joined: Wed Nov 05, 2008 12:16 pm
Has thanked: 2683 times
Been thanked: 831 times

Re: [HELP] Where to start on creating a model/animation view

Post by Acewell » Thu Mar 09, 2017 5:09 am

yeah i suppose you could write a dll plugin from C/C#/C++ code, i'm not 100% sure on the languages. :)

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Fri Mar 10, 2017 3:14 am

Thank you for your answers so far. If you were trying to do this yourself how would you go about it?

User avatar
Acewell
VIP member
VIP member
Posts: 1329
Joined: Wed Nov 05, 2008 12:16 pm
Has thanked: 2683 times
Been thanked: 831 times

Re: [HELP] Where to start on creating a model/animation view

Post by Acewell » Fri Mar 10, 2017 4:58 am

i'm not qualified to give input on C* language plugin development, i just tinker in python because it easy and fun :D
there is some plugin creation info at the bottom of the ReadMe.txt file that comes with noesis though that could
answer your questions better than i can. it mentions C and C++ so you should be good there, and examples are in
the "pluginsource.zip" that also comes with noesis. :)

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Sat Mar 11, 2017 1:31 am

Ill give it a shot, if it doesnt work out ill try python as well. Thanks alot!

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Sun May 14, 2017 5:55 pm

I have busy these past few months, so ive lost my drive a bit; but I am getting back into the swing of things. Instead of creating a separate exe that reads the .SKL and .DAM; I want to create a quickbms script to view the files on Noesis. I did a little searching through HxD and I've discovered that inside the SKL file's (Characters rig) offset shows a value of
00 11 00 00 00 01.

Image

I thought to myself, "Oh hey, I think I found a pattern here!" so I conducted a search using the same hex-value and-

Image

Uh-oh! Looks like I ran into a problem here! There aren't any more hex-values that match! I looked into the problem and found out that a similar pattern exists, but the 3rd and 4th digit in the hex-value are different. (I don't think I explained that correctly in hex format and I don't really care.)

Example:
if you look at offset 8E and block 8E-96 (I have that highlighted in red at the bottom left of the screencap) it shows "RightFoot" on the right.

Image




After the right foot, it shows a bunch of dots "......" which on the left side of HxD you will see 00 11 00 00 00 01 (6-bytes in length)

Image

Now look at this screencap:

Image

It shows a different bodypart "RightLowLeg", and the hex value in the "......" portion is slightly altered by 4 bytes.


So I figure I'm in the clear, and can get to the root of my problem when I discover that each hex prior to the body part has a unique length.

Image

I just cant catch a break today. It shows that the length prior to reaching the first body-part is 8E. Now your wondering, "hey askb, its probably the pattern used to distinguish and separate each body part."

I mean, it is; but its not consistent. After the 6-byte length pattern that I had noticed prior before the next body-part; I find another pattern that has a length of A8; I'm assuming this is the data of the file.

Image

This pattern continues RightFoot, RightLowLeg, and RightUpLeg; then I reach LeftFoot and it gives me a new length of AD

Image

It seems that after the hex gets to another section of the body altogether (IE: Right side of body to left side, left side to chest, chest to neck) it continues to the pattern of A8 in length (LeftFoot, LeftLowLeg, LeftUpLeg have a length of A8 after the 6 byte "......")

The pattern goes like this:

-Has a Unique pattern in length (specifc sections of the body (Legs, arms, chest, neck, etc))
-Has a consistent pattern of A8 in Length (Separate body-parts from the section: LeftFoot, LeftLowLeg, LeftUpLeg)
-Has an ending value of 2C (After the 6-byte "......" from Chest)

I must have been dropped on my head recently, but I can't seem to remember how to do anything up to this point. I even completely forgot how to tell the difference between endian.

User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 3189
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 875 times
Been thanked: 1753 times

Re: [HELP] Where to start on creating a model/animation view

Post by shakotay2 » Mon May 15, 2017 7:45 am

For "RightFoot 00 11 000000":
First zero is the zero termination of the string "RightFoot".
DWORD 11 00 00 00 (little endian) is 17 decimal, boneID (or parenting ID?)

(If it's the parenting ID then the boneID can be derived from the string order probably,
first bone name, 'root' for example, bone ID=0, 2nd bone name, bone ID=1, etc)

I usually proceed like this:
  • getting bone names
  • getting bone IDs and parenting IDs
  • looking for hierarchy table (parenting)
  • looking for matrices
(4x4 in most cases, rotation matrix and translation vector)

(If you uploaded hsf_exce1_a.skl I could have a look at.)
Bigchillghost, Reverse Engineering a Game Model: viewtopic.php?f=29&t=17889
extracting simple models: viewtopic.php?f=29&t=10894
Make_H2O-ForzaHor3-jm9.zip
"You quoted the whole thing, what a mess."

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Tue May 16, 2017 1:58 am

Sure thing, here's the file. In the meantime, im gonna search through the .DAM(animation) file; and see if i can find any patterns with that.
You do not have the required permissions to view the files attached to this post.

majidemo
advanced
Posts: 71
Joined: Sun Aug 21, 2016 12:00 am
Has thanked: 29 times
Been thanked: 33 times

Re: [HELP] Where to start on creating a model/animation view

Post by majidemo » Tue May 16, 2017 3:29 am

askB wrote:Sure thing, here's the file. In the meantime, im gonna search through the .DAM(animation) file; and see if i can find any patterns with that.
looking at this
Image

I'm thinking its

Code: Select all

~~UInt32 LE = Parent ID (notice some is repeated)~~ (scratch this, as shakotay2 said its actually the string size)
C String = Name (null-terminated)
UInt32 LE = Bone ID (notice all is unique)
UInt8 1 (always 1)
Bunch-of-Floats (variable length, some is 33 floats long like the RightFoot, or 41 floats long for the RightLowLeg)
Looking for this pattern "00 00 00 01" will give you 19 results or (number of bones + 1). You can find number of bones at offset 0x04. "12 00" = 18.
Last edited by majidemo on Tue May 16, 2017 9:44 pm, edited 1 time in total.

User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 3189
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 875 times
Been thanked: 1753 times

Re: [HELP] Where to start on creating a model/animation view

Post by shakotay2 » Tue May 16, 2017 9:24 pm

just another annoying format? breaking the matrices' analysing by purging some 01/00 sequences in between
which doesn't make sense to me:
bone_matrix.jpg
edit: I'd say those 01010100.. are some starting sequence for bone data (0x09: lower body, 0x464: upper body),
so the rotation matrix of RightHand to start at 0x48B with a rotation angle of zero degree?

(offset 0x23A, 0x750: 0100 0100 xx might separate between right and left side, just a wild guess)

Assuming the positions to be located at
offset 0x5E for RightFoot 8.4425 -94.846 0.9284
and 0x28B: for LefttFoot -9.185 -94.8 0.268
-----------------------------------------

LeftLowLeg
# 0x381:
0.000000 -22.007288 0.552109
22.014198 -0.771508 -49.444622
0.815535 -0.771508 0.000000
0.815535 8.392866 -9.184999
-4.152500 -0.000000 0.000000
-0.000000 0.000000 1.000000

1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
0.000000 0.000000 0.000000

v -9.184999 -4.152500 -0.000000
0.000000 0.000000 0.000000
1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
# 0x429


RightCollar 0100 0100 010000


LeftUpLeg
# 0x438:
0.000000 -23.314224 -0.418062
23.317944 -1.970615 -54.207619
-1.123106 -1.970615 0.000000
-1.123106 15.045624

010101 ..01 0000 sequence

# 0x46f:
-0.000000 -27.445000 -0.000000
0.000000 -0.000000 0.000000
1.000000

1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
0.000000 0.000000 0.000000

20.502531 -9.843071 0.078699
0.000000 0.000000 0.000000 1.000000
0.000000 0.000000 0.000000 1.000000
# 0x4e7

btw: bonename strings zero terminated plus leading DWORD char count+1
You do not have the required permissions to view the files attached to this post.
Bigchillghost, Reverse Engineering a Game Model: viewtopic.php?f=29&t=17889
extracting simple models: viewtopic.php?f=29&t=10894
Make_H2O-ForzaHor3-jm9.zip
"You quoted the whole thing, what a mess."

User avatar
askB
advanced
Posts: 43
Joined: Mon Feb 06, 2012 3:52 am
Has thanked: 6 times

Re: [HELP] Where to start on creating a model/animation view

Post by askB » Tue Jun 13, 2017 1:34 am

~~UInt32 LE = Parent ID (notice some is repeated)~~ (scratch this, as shakotay2 said its actually the string size)
C String = Name (null-terminated)
UInt32 LE = Bone ID (notice all is unique)
UInt8 1 (always 1)
Bunch-of-Floats (variable length, some is 33 floats long like the RightFoot, or 41 floats long for the RightLowLeg)

I did some studying on the script template for noesis; I am having a hard time understanding how i would be able to put something like this into one of the templates they provide.

Code: Select all

#Noesis Python model import+export test module, imports/exports some data from/to a made-up format

from inc_noesis import *

import noesis

#rapi methods should only be used during handler callbacks
import rapi

#registerNoesisTypes is called by Noesis to allow the script to register formats.
#Do not implement this function in script files unless you want them to be dedicated format modules!
def registerNoesisTypes():
	handle = noesis.register("Noesis Python Test Model", ".noepy")
	noesis.setHandlerTypeCheck(handle, noepyCheckType)
	noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG
	noesis.setHandlerWriteModel(handle, noepyWriteModel)
	noesis.setHandlerWriteAnim(handle, noepyWriteAnim)

	#noesis.logPopup()
	#print("The log can be useful for catching debug prints from preview loads.\nBut don't leave it on when you release your script, or it will probably annoy people.")
	return 1

NOEPY_HEADER = 0x1337455
NOEPY_VERSION = 0x7178173

#check if it's this type based on the data
def noepyCheckType(data):
	if len(data) < 8:
		return 0
	bs = NoeBitStream(data)

	if bs.readInt() != NOEPY_HEADER:
		return 0
	if bs.readInt() != NOEPY_VERSION:
		return 0

	return 1

#load the model
def noepyLoadModel(data, mdlList):
	bs = NoeBitStream(data)
	if bs.readInt() != NOEPY_HEADER:
		return 0
	if bs.readInt() != NOEPY_VERSION:
		return 0

	meshes = []
	numMeshes = bs.readInt()
	for i in range(0, numMeshes):
		meshName = bs.readString()
		meshMat = bs.readString()
		numIdx = bs.readInt()
		numPos = bs.readInt()
		numNrm = bs.readInt()
		numUVs = bs.readInt()
		numTan = bs.readInt()
		numClr = bs.readInt()
		numWeights = bs.readInt()
		idxList = []
		posList = []
		for j in range(0, numIdx):
			idxList.append(bs.readInt())
		for j in range(0, numPos):
			posList.append(NoeVec3.fromBytes(bs.readBytes(12)))
		mesh = NoeMesh(idxList, posList, meshName, meshMat)
		for j in range(0, numNrm):
			mesh.normals.append(NoeVec3.fromBytes(bs.readBytes(12)))
		for j in range(0, numUVs):
			mesh.uvs.append(NoeVec3.fromBytes(bs.readBytes(12)))
		for j in range(0, numTan):
			mesh.tangents.append(NoeMat43.fromBytes(bs.readBytes(48)))
		for j in range(0, numClr):
			mesh.colors.append(NoeVec4.fromBytes(bs.readBytes(16)))
		for j in range(0, numWeights):
			vwNum = bs.readInt()
			bidx = []
			bwgt = []
			for k in range(0, vwNum):
				bidx.append(bs.readInt())
			for k in range(0, vwNum):
				bwgt.append(bs.readFloat())
			mesh.weights.append(NoeVertWeight(bidx, bwgt))
		mfList = []
		numMorphFrames = bs.readInt()
		for j in range(0, numMorphFrames):
			morphPL = []
			morphNL = []
			numPos = bs.readInt()
			numNrm = bs.readInt()
			for k in range(0, numPos):
				vec = NoeVec3.fromBytes(bs.readBytes(12))
				morphPL.append(vec)
			for k in range(0, numNrm):
				vec = NoeVec3.fromBytes(bs.readBytes(12))
				morphNL.append(vec)
			mf = NoeMorphFrame(morphPL, morphNL)
			mfList.append(mf)
		mesh.setMorphList(mfList)
		meshes.append(mesh)

	bones = []
	numBones = bs.readInt()
	for i in range(0, numBones):
		bone = noepyReadBone(bs)
		bones.append(bone)

	anims = []
	numAnims = bs.readInt()
	for i in range(0, numAnims):
		animName = bs.readString()
		numAnimBones = bs.readInt()
		animBones = []
		for j in range(0, numAnimBones):
			animBone = noepyReadBone(bs)
			animBones.append(animBone)
		animNumFrames = bs.readInt()
		animFrameRate = bs.readFloat()
		numFrameMats = bs.readInt()
		animFrameMats = []
		for j in range(0, numFrameMats):
			frameMat = NoeMat43.fromBytes(bs.readBytes(48))
			animFrameMats.append(frameMat)
		anim = NoeAnim(animName, animBones, animNumFrames, animFrameMats, animFrameRate)
		anims.append(anim)

	mdl = NoeModel(meshes, bones, anims)
	mdlList.append(mdl)			#important, don't forget to put your loaded model in the mdlList

	#this would be the default offset for quake models
	#rapi.setPreviewOption("setAngOfs", "0 180 0")
	return 1

#write it
def noepyWriteModel(mdl, bs):
	anims = rapi.getDeferredAnims()

	bs.writeInt(NOEPY_HEADER)
	bs.writeInt(NOEPY_VERSION)

	bs.writeInt(len(mdl.meshes))
	for mesh in mdl.meshes:
		bs.writeString(mesh.name)
		bs.writeString(mesh.matName)
		bs.writeInt(len(mesh.indices))
		bs.writeInt(len(mesh.positions))
		bs.writeInt(len(mesh.normals))
		bs.writeInt(len(mesh.uvs))
		bs.writeInt(len(mesh.tangents))
		bs.writeInt(len(mesh.colors))
		bs.writeInt(len(mesh.weights))
		for idx in mesh.indices:
			bs.writeInt(idx)
		for vcmp in mesh.positions:
			bs.writeBytes(vcmp.toBytes())
		for vcmp in mesh.normals:
			bs.writeBytes(vcmp.toBytes())
		for vcmp in mesh.uvs:
			bs.writeBytes(vcmp.toBytes())
		for vcmp in mesh.tangents:
			bs.writeBytes(vcmp.toBytes())
		for vcmp in mesh.colors:
			bs.writeBytes(vcmp.toBytes())
		for vcmp in mesh.weights:
			bs.writeInt(vcmp.numWeights())
			for wval in vcmp.indices:
				bs.writeInt(wval)
			for wval in vcmp.weights:
				bs.writeFloat(wval)
		bs.writeInt(len(mesh.morphList))
		for mf in mesh.morphList:
			bs.writeInt(len(mf.positions))
			bs.writeInt(len(mf.normals))
			for vec in mf.positions:
				bs.writeBytes(vec.toBytes())
			for vec in mf.normals:
				bs.writeBytes(vec.toBytes())

	bs.writeInt(len(mdl.bones))
	for bone in mdl.bones:
		noepyWriteBone(bs, bone)

	bs.writeInt(len(anims))
	for anim in anims:
		bs.writeString(anim.name)
		bs.writeInt(len(anim.bones))
		for bone in anim.bones:
			noepyWriteBone(bs, bone)
		bs.writeInt(anim.numFrames)
		bs.writeFloat(anim.frameRate)
		bs.writeInt(len(anim.frameMats))
		for mat in anim.frameMats:
			bs.writeBytes(mat.toBytes())

	return 1

#when you want animation data to be written out with a model format, you should make a handler like this that catches it and defers it
def noepyWriteAnim(anims, bs):
	#it's good practice for an animation-deferring handler to inform the user that the format only supports joint model-anim export
	if rapi.isGeometryTarget() == 0:
		print("WARNING: Stand-alone animations cannot be written to the .noepy format.")
		return 0

	rapi.setDeferredAnims(anims)
	return 0

#write bone
def noepyWriteBone(bs, bone):
	bs.writeInt(bone.index)
	bs.writeString(bone.name)
	bs.writeString(bone.parentName)
	bs.writeInt(bone.parentIndex)
	bs.writeBytes(bone.getMatrix().toBytes())

#read bone
def noepyReadBone(bs):
	boneIndex = bs.readInt()
	boneName = bs.readString()
	bonePName = bs.readString()
	bonePIndex = bs.readInt()
	boneMat = NoeMat43.fromBytes(bs.readBytes(48))
	return NoeBone(boneIndex, boneName, boneMat, bonePName, bonePIndex)




#demonstrates using the rich procedural geometry interface to draw the model into memory, instead of a direct data load
#(not actually used by the script)
def noepyLoadModelRPG(data, mdlList):
	bs = NoeBitStream(data)
	if bs.readInt() != NOEPY_HEADER:
		return 0
	if bs.readInt() != NOEPY_VERSION:
		return 0

	#no need to explicitly free the context (created contexts are auto-freed after the handler), but DO NOT hold any references to it outside of this method
	ctx = rapi.rpgCreateContext()

	numMeshes = bs.readInt()
	for i in range(0, numMeshes):
		meshName = bs.readString()
		meshMat = bs.readString()
		numIdx = bs.readInt()
		numPos = bs.readInt()
		numNrm = bs.readInt()
		numUVs = bs.readInt()
		numTan = bs.readInt()
		numClr = bs.readInt()
		numWeights = bs.readInt()

		rapi.rpgSetName(meshName)
		rapi.rpgSetMaterial(meshMat)

		triangles = bs.readBytes(numIdx * 4)
		positions = bs.readBytes(numPos * 12)
		normals = bs.readBytes(numPos * 12) if numNrm == numPos else None
		uvs = bs.readBytes(numPos * 12) if numUVs == numPos else None
		tans = bs.readBytes(numPos * 48) if numTan == numPos else None
		colors = bs.readBytes(numPos * 16) if numClr == numPos else None

		rapi.rpgBindPositionBuffer(positions, noesis.RPGEODATA_FLOAT, 12)
		rapi.rpgBindNormalBuffer(normals, noesis.RPGEODATA_FLOAT, 12)
		rapi.rpgBindUV1Buffer(uvs, noesis.RPGEODATA_FLOAT, 12)
		rapi.rpgBindColorBuffer(colors, noesis.RPGEODATA_FLOAT, 16, 4)
		if numWeights > 0:
			vwList = []
			for j in range(0, numWeights):
				vwNum = bs.readInt()
				bidx = []
				bwgt = []
				for k in range(0, vwNum):
					bidx.append(bs.readInt())
				for k in range(0, vwNum):
					bwgt.append(bs.readFloat())
				vwList.append(NoeVertWeight(bidx, bwgt))
			fw = NoeFlatWeights(vwList)
			rapi.rpgBindBoneIndexBuffer(fw.flatW[:fw.weightValOfs], noesis.RPGEODATA_INT, 4*fw.weightsPerVert, fw.weightsPerVert)
			rapi.rpgBindBoneWeightBuffer(fw.flatW[fw.weightValOfs:], noesis.RPGEODATA_FLOAT, 4*fw.weightsPerVert, fw.weightsPerVert)
		numMorphFrames = bs.readInt()
		for j in range(0, numMorphFrames):
			numMFPos = bs.readInt()
			numMFNrm = bs.readInt()
			morphPosAr = bs.readBytes(numMFPos * 12)
			rapi.rpgFeedMorphTargetPositions(morphPosAr, noesis.RPGEODATA_FLOAT, 12)
			if numMFNrm > 0:
				morphNrmAr = bs.readBytes(numMFNrm * 12)
				rapi.rpgFeedMorphTargetNormals(morphNrmAr, noesis.RPGEODATA_FLOAT, 12)
			rapi.rpgCommitMorphFrame(numMFPos)
		rapi.rpgCommitMorphFrameSet()

		rapi.rpgCommitTriangles(triangles, noesis.RPGEODATA_INT, numIdx, noesis.RPGEO_TRIANGLE, 1)
		rapi.rpgClearBufferBinds() #reset in case a subsequent mesh doesn't have the same components

		#the mesh could also be drawn in immediate mode like this:
		#rapi.immBegin(noesis.RPGEO_TRIANGLE)
		#for i in range(0, numIdx):
		#	idx = noeUnpackFrom("<i", triangles, i*4)[0]
		#	vcmp = noeUnpackFrom("<ff", uvs, idx*12)
		#	rapi.immUV2(vcmp)
		#	vcmp = noeUnpackFrom("<fff", normals, idx*12)
		#	rapi.immNormal3(vcmp)
		#	vcmp = noeUnpackFrom("<" + "i"*fw.weightsPerVert, fw.flatW, idx*4*fw.weightsPerVert)
		#	rapi.immBoneIndex(vcmp)
		#	vcmp = noeUnpackFrom("<" + "f"*fw.weightsPerVert, fw.flatW, fw.weightValOfs + idx*4*fw.weightsPerVert)
		#	rapi.immBoneWeight(vcmp)
		#	vcmp = noeUnpackFrom("<fff", positions, idx*12)
		#	rapi.immVertex3(vcmp)
		#rapi.immEnd()

	mdl = rapi.rpgConstructModel()

	bones = []
	numBones = bs.readInt()
	for i in range(0, numBones):
		bone = noepyReadBone(bs)
		bones.append(bone)

	anims = []
	numAnims = bs.readInt()
	for i in range(0, numAnims):
		animName = bs.readString()
		numAnimBones = bs.readInt()
		animBones = []
		for j in range(0, numAnimBones):
			animBone = noepyReadBone(bs)
			animBones.append(animBone)
		animNumFrames = bs.readInt()
		animFrameRate = bs.readFloat()
		numFrameMats = bs.readInt()
		animFrameMats = []
		for j in range(0, numFrameMats):
			frameMat = NoeMat43.fromBytes(bs.readBytes(48))
			animFrameMats.append(frameMat)
		anim = NoeAnim(animName, animBones, animNumFrames, animFrameMats, animFrameRate)
		anims.append(anim)

	mdl.setBones(bones)
	mdl.setAnims(anims)
	mdlList.append(mdl)			#important, don't forget to put your loaded model in the mdlList
	return 1

Would I be able to use something like this? It searches for the amount of bones and bodyparts that are on the model it is trying to import.

Post Reply