Code Vonc

Import Racer DOF

v 1.0

Python pour Cinéma 4D R15.

TéléchargerDownload
Faire un donMake a donation
Comment installer ?How to install ?
CommentairesComments

Filtre d'importation de fichiers de géométrie du jeu Racer (*.dof).


Copier le dossier « vonc_racerdof » dans le dossier « plugins » du répertoire de Cinéma 4D.



Codes sources


Fichier vonc_racerdof.PYP :

import os
import c4d
import struct as st
from c4d import plugins, utils, Vector, CPolygon

MODULE_ID = 1028098

class ImporteurDof(plugins.SceneLoaderData) :
	f = None
	
	def _vecCoul(self, coul) :
		return Vector(coul['r'], coul['v'], coul['b'])
	
	def _etiq(self) :
		return st.unpack('<4s', self.f.read(4))[0]
	
	def _entier(self) :
		return st.unpack('<I', self.f.read(4))[0]
	
	def _entier16(self) :
		return st.unpack('<H', self.f.read(2))[0]
	
	def _flottant(self) :
		return st.unpack('<f', self.f.read(4))[0]
	
	def _texte(self, long = None) :
		if not long : long = self._entier16()
		if long == 0 : return ""
		texte = st.unpack('<' + str(long) + 's', self.f.read(long))
		return texte[0]
	
	def _vecteur(self) :
		vec = Vector()
		vec_tab = st.unpack('<fff', self.f.read(12))
		vec.x = vec_tab[0]
		vec.y = vec_tab[1]
		vec.z = vec_tab[2]
		return vec
	
	def _vecteur2(self) :
		vec = Vector()
		vec_tab = st.unpack('<ff', self.f.read(8))
		vec.x = vec_tab[0]
		vec.y = vec_tab[1]
		return vec
	
	def _triangle(self) :
		tab = st.unpack('<HHH', self.f.read(6))
		tri = CPolygon(tab[2], tab[1], tab[0], tab[0])
		return tri
	
	def _couleur(self, alpha = True) :
		coul = {}
		coul['r'] = self._flottant()
		coul['v'] = self._flottant()
		coul['b'] = self._flottant()
		coul['a'] = 1.0
		if alpha : coul['a'] = self._flottant()
		return coul
	
	def _lireInconnu(self) :
		long = self._entier()
		self.f.read(long)
	
	def _lireMSUB(self, mat) : # Sous-matériaux ?
		long = self._entier()
		self.f.read(long)
		return mat
	
	def _lireMTEX(self, mat) :
		long = self._entier()
		nbtex = self._entier()
		textures = []
		for i in xrange(nbtex) :
			textures.append(self._texte())
		mat['textures'] = textures
		return mat
		
	def _lireMCFL(self, mat) :
		long = self._entier()
		mat['environnement'] = self._entier() # (1 = texture d'environnement activée)
		return mat
	
	def _lireMTRA(self, mat) :
		long = self._entier()
		mat['transparence'] = self._flottant()
		mat['melange'] = self._entier() # (0 = pas de mélange, 1 = BLEND_SRC_ALPHA = source Alpha, 2 = BLEND_CONST = "constant color blending" (inutilisé))
		return mat
	
	def _lireMUVW(self, mat) :
		long = self._entier()
		mat['decalageU'] = self._flottant()
		mat['decalageV'] = self._flottant()
		mat['repetitionsU'] = self._flottant()
		mat['repetitionsV'] = self._flottant()
		mat['angleUVW'] = self._flottant()
		mat['flou'] = self._flottant()
		mat['flouDecalage'] = self._flottant()
		return mat
	
	def _lireMCOL(self, mat) :
		long = self._entier()
		mat['ambiante'] = self._couleur()
		mat['diffuse'] = self._couleur()
		mat['specularite'] = self._couleur()
		mat['emission'] = self._couleur()
		mat['eclat'] = self._flottant()
		return mat
	
	def _lireMHDR(self, mat) :
		long = self._entier()
		mat['nom'] = self._texte()
		mat['propriete'] = self._texte()
		return mat
	
	def _lireMAT0(self) :
		materiau = {} # Valeurs par défaut
		materiau['nom'] = "Mat"
		materiau['propriete'] = ""
		materiau['ambiante'] = {'r':0.0, 'v':0.0, 'b':0.0, 'a':1.0}
		materiau['diffuse'] = {'r':1.0, 'v':1.0, 'b':1.0, 'a':1.0}
		materiau['specularite'] = {'r':1.0, 'v':1.0, 'b':1.0, 'a':1.0}
		materiau['emission'] = {'r':0.0, 'v':0.0, 'b':0.0, 'a':0.0}
		materiau['eclat'] = 0.0
		materiau['decalageU'] = 0.0
		materiau['decalageV'] = 0.0
		materiau['repetitionsU'] = 1.0
		materiau['repetitionsV'] = 1.0
		materiau['angleUVW'] = 0.0
		materiau['flou'] = 0.0
		materiau['flouDecalage'] = 0.0
		materiau['transparence'] = 0.0
		materiau['melange'] = 0
		materiau['environnement'] = 0
		materiau['textures'] = []
		materiau['c4dMat'] = None
		
		long = self._entier()
		etiquette = self._etiq()
		
		while etiquette != 'MEND' :
			if etiquette == 'MHDR' : materiau = self._lireMHDR(materiau)
			elif etiquette == 'MCOL' : materiau = self._lireMCOL(materiau)
			elif etiquette == 'MUVW' : materiau = self._lireMUVW(materiau)
			elif etiquette == 'MTRA' : materiau = self._lireMTRA(materiau)
			elif etiquette == 'MCFL' : materiau = self._lireMCFL(materiau)
			elif etiquette == 'MTEX' : materiau = self._lireMTEX(materiau)
			elif etiquette == 'MSUB' : materiau = self._lireMSUB(materiau)
			# else : self._lireInconnu()
			etiquette = self._etiq()
		
		return materiau
	
	def _lireMATS(self, filterflags) :
		long = self._entier()
		if filterflags == c4d.SCENEFILTER_OBJECTS :
			self.f.read(long)
			return []
		
		materiaux = []
		nbmats = self._entier()
		
		for i in xrange(nbmats) :
			materiau = None
			if self._etiq() == 'MAT0' :
				materiau = self._lireMAT0()
			
			if materiau : materiaux.append(materiau)
		
		return materiaux
	
	def _lireBRST(self, objet) : # "bursts of equal-state triangles"
		long = self._entier()
		self.f.read(long)
		return objet
	
	def _lireVCOL(self, objet) :
		long = self._entier()
		objet['couleurs_tot'] = self._entier()
		coul = []
		for i in xrange(objet['couleurs_tot']) :
			coul.append(self._vecteur())
		objet['couleurs'] = coul
		return objet
		
	def _lireNORM(self, objet) :
		long = self._entier()
		objet['normales_tot'] = self._entier()
		norm = []
		for i in xrange(objet['normales_tot']) :
			norm.append(self._vecteur())
		objet['normales'] = norm
		return objet
		
	def _lireTVER(self, objet) :
		long = self._entier()
		objet['uv_tot'] = self._entier()
		uv = []
		for i in xrange(objet['uv_tot']) :
			vec = self._vecteur2()
			vec.y = -vec.y + 1.0
			uv.append(vec)
		objet['uv'] = uv
		return objet
		
	def _lireVERT(self, objet) :
		long = self._entier()
		objet['sommets_tot'] = self._entier()
		som = []
		for i in xrange(objet['sommets_tot']) :
			vec = self._vecteur() * 100.0
			vec.x = -vec.x
			som.append(vec)
		objet['sommets'] = som
		return objet
		
	def _lireINDI(self, objet) :
		long = self._entier()
		tot = self._entier()
		tri_nb = int(tot / 3.0)
		objet['triangles_tot'] = tri_nb
		tri = []
		for i in xrange(tri_nb) :
			tri.append(self._triangle())
		objet['triangles'] = tri
		return objet
	
	def _lireGHDR(self, objet) :
		long = self._entier()
		objet['inu0'] = self._entier()
		objet['paintFlags'] = self._entier()
		objet['materiau'] = self._entier()
		return objet
	
	def _lireGOB1(self) :
		objet = {} # Valeurs par défaut
		objet['inu0'] = 0 # Actuellement inutilisé
		objet['paintFlags'] = 0 # Actuellement inutilisé
		objet['materiau'] = 0
		objet['triangles_tot'] = 0
		objet['triangles'] = []
		objet['sommets_tot'] = 0
		objet['sommets'] = []
		objet['uv_tot'] = 0
		objet['uv'] = []
		objet['normales_tot'] = 0
		objet['normales'] = []
		
		long = self._entier()
		etiquette = self._etiq()
		
		while etiquette != 'GEND' :
			if etiquette == 'GHDR' : objet = self._lireGHDR(objet)
			elif etiquette == 'INDI' : objet = self._lireINDI(objet)
			elif etiquette == 'VERT' : objet = self._lireVERT(objet)
			elif etiquette == 'TVER' : objet = self._lireTVER(objet)
			elif etiquette == 'NORM' : objet = self._lireNORM(objet)
			elif etiquette == 'VCOL' : objet = self._lireVCOL(objet)
			elif etiquette == 'BRST' : objet = self._lireBRST(objet)
			# else : self._lireInconnu()
			etiquette = self._etiq()
		
		return objet
	
	def _lireGEOB(self, filterflags) :
		long = self._entier()
		if filterflags == c4d.SCENEFILTER_MATERIALS :
			self.f.read(long)
			return []
		
		objets = []
		nbobjs = self._entier()
		
		for i in xrange(nbobjs) :
			objet = None
			if self._etiq() == 'GOB1' :
				objet = self._lireGOB1()
			
			if objet : objets.append(objet)
		
		return objets
	
	def _CreerMats(self, doc, materiaux) :
		if not materiaux : return
		for materiau in materiaux :
			c4dMat = c4d.BaseMaterial(c4d.Mmaterial)
			c4dMat[c4d.ID_BASELIST_NAME] = materiau['nom']
			c4dMat[c4d.MATERIAL_USE_COLOR] = True
			c4dMat[c4d.MATERIAL_COLOR_COLOR] = self._vecCoul(materiau['diffuse'])
			c4dMat[c4d.MATERIAL_COLOR_BRIGHTNESS] = materiau['diffuse']['a']
			# c4dMat[c4d.MATERIAL_COLOR_TEXTUREMIXING] = c4d.MATERIAL_TEXTUREMIXING_MULTIPLY
			if materiau['textures'] :
				c4dMat_coul = c4d.BaseList2D(c4d.Xbitmap)
				c4dMat_coul[c4d.BITMAPSHADER_FILENAME] = materiau['textures'][0]
				c4dMat.InsertShader(c4dMat_coul)
				c4dMat[c4d.MATERIAL_COLOR_SHADER] = c4dMat_coul
				if materiau['melange'] == 1 :
					c4dMat[c4d.MATERIAL_USE_ALPHA] = True
					c4dMat_alpha = c4d.BaseList2D(c4d.Xbitmap)
					c4dMat_alpha[c4d.BITMAPSHADER_FILENAME] = materiau['textures'][0]
					c4dMat.InsertShader(c4dMat_alpha)
					c4dMat[c4d.MATERIAL_ALPHA_SHADER] = c4dMat_alpha
			c4dMat[c4d.MATERIAL_USE_SPECULAR] = True
			c4dMat[c4d.MATERIAL_SPECULAR_COLOR] = self._vecCoul(materiau['specularite'])
			c4dMat[c4d.MATERIAL_SPECULAR_BRIGHTNESS] = materiau['specularite']['a']
			c4dMat[c4d.MATERIAL_SPECULAR_HEIGHT] = materiau['eclat'] * 0.01
			if materiau['emission']['a'] :
				c4dMat[c4d.MATERIAL_USE_LUMINANCE] = True
				c4dMat[c4d.MATERIAL_LUMINANCE_COLOR] = self._vecCoul(materiau['emission'])
				c4dMat[c4d.MATERIAL_LUMINANCE_BRIGHTNESS] = materiau['emission']['a']
			
			doc.InsertMaterial(c4dMat)
			materiau['c4dMat'] = c4dMat
	
	def _CreerObjets(self, doc, objets, materiaux, nom) :
		if not objets : return
		
		neutre = c4d.BaseObject(c4d.Onull)
		neutre.SetName(nom)
		
		for objet in objets :
			c4dObj = c4d.BaseObject(c4d.Opolygon)
			c4dObj_nbpts = objet['sommets_tot']
			c4dObj_nbtris = objet['triangles_tot']
			c4dObj_triangles = objet['triangles']
			c4dObj.ResizeObject(c4dObj_nbpts, c4dObj_nbtris)
			c4dObj.SetAllPoints(objet['sommets'])
			for p in xrange(c4dObj_nbtris) :
				c4dObj.SetPolygon(p, c4dObj_triangles[p])
			
			c4dObj_mat = materiaux[objet['materiau']]
			c4dObj_tex = c4dObj.MakeTag(c4d.Ttexture)
			c4dObj_tex[c4d.TEXTURETAG_MATERIAL] = c4dObj_mat['c4dMat']
			c4dObj_tex[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_UVW
			c4dObj_tex[c4d.TEXTURETAG_OFFSETX] = c4dObj_mat['decalageU']
			c4dObj_tex[c4d.TEXTURETAG_OFFSETY] = c4dObj_mat['decalageV']
			c4dObj_tex[c4d.TEXTURETAG_TILESX] = c4dObj_mat['repetitionsU']
			c4dObj_tex[c4d.TEXTURETAG_TILESY] = c4dObj_mat['repetitionsV']
			
			uv = objet['uv']
			if uv :
				c4dObj_uvw = c4dObj.MakeVariableTag(c4d.Tuvw, c4dObj_nbtris)
				for p in xrange(c4dObj_nbtris) :
					tri = c4dObj_triangles[p]
					c4dObj_uvw.SetSlow(p, uv[tri.a], uv[tri.b], uv[tri.c], uv[tri.c])
			
			c4dObj_phong = c4dObj.MakeTag(c4d.Tphong)
			
			norm = objet['normales']
			if norm :
				c4dObj_nor = c4dObj.MakeVariableTag(c4d.Tnormal, c4dObj_nbtris * 12)
				norm_liste = []
				for p in xrange(c4dObj_nbtris) :
					tri = c4dObj_triangles[p]
					norm_liste.append(int(norm[tri.a].x * -1000))
					norm_liste.append(int(norm[tri.a].y * 1000))
					norm_liste.append(int(norm[tri.a].z * 1000))
					norm_liste.append(int(norm[tri.b].x * -1000))
					norm_liste.append(int(norm[tri.b].y * 1000))
					norm_liste.append(int(norm[tri.b].z * 1000))
					norm_liste.append(int(norm[tri.c].x * -1000))
					norm_liste.append(int(norm[tri.c].y * 1000))
					norm_liste.append(int(norm[tri.c].z * 1000))
					norm_liste.append(int(norm[tri.d].x * -1000))
					norm_liste.append(int(norm[tri.d].y * 1000))
					norm_liste.append(int(norm[tri.d].z * 1000))
				c4dObj_nor.SetAllHighlevelData(norm_liste)
				c4dObj_phong[c4d.PHONGTAG_PHONG_ANGLELIMIT] = False
				
			c4dObj.Message(c4d.MSG_UPDATE)
			c4dObj.InsertUnder(neutre)
		
		doc.InsertObject(neutre)
	
	def Identify(self, node, name, probe, size) :
		nom = name.lower()
		
		if not nom.endswith('.dof') : return False
		
		tampon = probe[0:4]
		entete = st.unpack('<4s', tampon)
		if entete[0] != 'DOF1' : return False
		
		return True
	
	def Load(self, node, name, doc, filterflags, error, bt) :
		if not name : return c4d.FILEERROR_OPEN
		chemin = name.decode('UTF-8', 'strict')
		
		try : self.f = open(chemin, 'rb')
		except IOError : return c4d.FILEERROR_OPEN
		if not self.f : return c4d.FILEERROR_OPEN
		
		nomext = os.path.basename(chemin)
		nom = os.path.splitext(nomext)[0]
		materiaux = []
		objets = []
		
		self.f.read(4) # DOF1
		self.f.read(4) # Taille jusqu'à EDOF
		
		etiquette = self._etiq()
		while etiquette != 'EDOF' :
			if etiquette == 'MATS' : materiaux = self._lireMATS(filterflags)
			elif etiquette == 'GEOB' : objets = self._lireGEOB(filterflags)
			# else : self._lireInconnu()
			etiquette = self._etiq()
		
		self._CreerMats(doc, materiaux)
		self._CreerObjets(doc, objets, materiaux, nom)
		
		
		self.f.close()
		c4d.EventAdd()
		return c4d.FILEERROR_NONE

if __name__=='__main__':
	plugins.RegisterSceneLoaderPlugin(id=MODULE_ID, 
									str="Racer DOF (*.dof)", 
									g=ImporteurDof, 
									info=0, 
									description="")