God Of War 3

Модели игровых персонажей. Люди, животные, пришельцы, роботы и т.д.
Ответить
Сообщение
Автор
HaCKer_UTD
Заинтересованный
Заинтересованный
Сообщения: 143
Зарегистрирован: 04 дек 2011, 15:25
Благодарил (а): 0
Поблагодарили: 0

God Of War 3

#1 Сообщение HaCKer_UTD »

Формат: *.obj
Kratos:
Изображение
https://yadi.sk/d/3eECeeLsbd6oi

Аватара пользователя
Tosyk
Администратор
Сообщения: 1880
Зарегистрирован: 24 авг 2011, 03:11
Благодарил (а): 64 раза
Поблагодарили: 61 раз

Re: God Of War 3

#2 Сообщение Tosyk »

ух ты, как это получилось?
При копировании материалов сайта ссылка на этот ресурс обязательна.
When copying materials from this site link to this resource is required.

HaCKer_UTD
Заинтересованный
Заинтересованный
Сообщения: 143
Зарегистрирован: 04 дек 2011, 15:25
Благодарил (а): 0
Поблагодарили: 0

Re: God Of War 3

#3 Сообщение HaCKer_UTD »

С челом одним формат разобрали.
У меня есть еще немного моделей, лень сюда выкладывать все.
http://hacker7utd.deviantart.com/gallery

Аватара пользователя
Tosyk
Администратор
Сообщения: 1880
Зарегистрирован: 24 авг 2011, 03:11
Благодарил (а): 64 раза
Поблагодарили: 61 раз

Re: God Of War 3

#4 Сообщение Tosyk »

поделишься способом?
При копировании материалов сайта ссылка на этот ресурс обязательна.
When copying materials from this site link to this resource is required.

HaCKer_UTD
Заинтересованный
Заинтересованный
Сообщения: 143
Зарегистрирован: 04 дек 2011, 15:25
Благодарил (а): 0
Поблагодарили: 0

Re: God Of War 3

#5 Сообщение HaCKer_UTD »

Код: Выделить всё

#############################################################
# God of War III model import script by maver1k_XVII        #
#############################################################
# Version 0.65 beta                                         #
#############################################################
# Special thanks to:                                        #
# * 3dformat from http://ps23dformat.wikispaces.com for     #
# the gow3WAD.bms script which I used as a base for further #
# research of this format                                   #
# * HaCKer_UTD for finding a way to decode triangle indices #
# and for the help with various other issues                #
#############################################################

from inc_noesis import *
from decimal import *

import noesis

import rapi

def registerNoesisTypes():
	handle = noesis.register("God of War 3 model", ".wad")
	noesis.setHandlerTypeCheck(handle, noepyCheckType)
	noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG
	#noesis.setHandlerWriteModel(handle, noepyWriteModel)
	#noesis.setHandlerWriteAnim(handle, noepyWriteAnim)
	noesis.logPopup()
	return 1

NOEPY_HEADER = ""

#check if it's this type based on the data
def noepyCheckType(data):
	return 1       

#load the model
def noepyLoadModel(data, mdlList):
	ctx = rapi.rpgCreateContext()
	model = GOWIII_WAD(data)
	mdlList.append(model.mdl)
	rapi.rpgClearBufferBinds()   
	return 1
   
class GOWIII_WAD:
	def __init__(self, data):
		self.bs = NoeBitStream(data)
		self.bs.setEndian(NOE_BIGENDIAN)
		rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1)
		rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1)
		self.FileInfo   = []
		self.TriGrpInfo   = []
		self.boneList   = []
		#self.animList   = []
		self.matList    = []
		self.texList    = []
		self.meshInfoTmp    = []  
		self.MeshNum    = 0 
		self.__parse__()
		return
        
	def __parse__(self):
		filesize = self.bs.getSize()
		filesizeDiv4 = filesize//4
		off2lastMesh = 0
		for i in range(0, filesizeDiv4-1):
			Temp = self.bs.readUInt64()
			offset = self.bs.tell()
			if (Temp == 0xFFFFFF9C00000000) or (Temp == 0xFFFFFF8C00000000):
				print('Model data found at offset {}...'.format(hex(offset - 0x8)))
				off2lastMesh = offset
				self.MeshNum += 1
				self.Vertex(offset - 0x8)
				#Temporary code to only view selected mesh
				"""if self.MeshNum == 3:
					self.Vertex(offset - 0x8)
				else:
					continue
				self.bs.seek(offset, NOESEEK_ABS)"""
				#break
			self.bs.seek(offset - 0x4, NOESEEK_ABS)
		#self.FindSkeleton(filesize, off2lastMesh)
		self.mdl = rapi.rpgConstructModel()
		self.mdl.setModelMaterials(NoeModelMaterials(self.texList, self.matList))
		self.mdl.setBones(self.boneList)
		#self.Animations()
		#self.mdl.setAnims(self.Animations())
		return
        
	def Vertex(self, off2vtx):
		self.meshInfoTmp = []
		self.bs.seek(off2vtx - 0x3C, NOESEEK_ABS)
		#VtxBytes = 0x18
		VtxNum = self.bs.readUShort()
		IdxNum = self.bs.readUShort()
		self.bs.seek(0x8, NOESEEK_REL)
		IdxOff = self.bs.readUInt()
		TempOff = self.bs.tell()
		self.bs.seek(IdxOff - 0x4, NOESEEK_REL)
		IdxOff = self.bs.tell()
		self.bs.seek(TempOff, NOESEEK_ABS)
		IdxSize = self.bs.readUShort()
		self.bs.seek(0x6, NOESEEK_REL)
		VtxOff = self.bs.readInt()
		self.bs.seek(0x4, NOESEEK_REL)
		VtxSize = self.bs.readUShort()
		self.bs.seek(VtxOff - 0xA, NOESEEK_REL)
		VtxBytes = VtxSize//VtxNum
		print(hex(self.bs.tell()))
		print(VtxNum)
		if VtxNum < 6:
			return
		elif (VtxNum == 512) or (VtxNum == 511):
			TempOff = self.bs.tell()
			VtxNum = self.ValidateVtxNum(off2vtx - 0x44)
			self.bs.seek(TempOff, NOESEEK_ABS)
			print(VtxNum)
			#print(self.meshInfoTmp)
		else:
			meshInf = [VtxNum, IdxNum, IdxOff, IdxSize, ]
			self.meshInfoTmp.append(meshInf)
			#print(self.meshInfoTmp)
		VtxOffCurr = self.bs.tell()
		if VtxNum % 2 == 0:
			UVOffCurr = VtxOffCurr + VtxNum * VtxBytes
		else:
			UVOffCurr = VtxOffCurr + VtxNum * VtxBytes + 0x8
		self.bs.seek(off2vtx - 0x4, NOESEEK_ABS)
		WeightOffCurr = self.bs.readInt()
		if WeightOffCurr != 0:
			WeightOffCurr += off2vtx - 0x4
		rapi.rpgSetMaterial(str(self.MeshNum))
		material = NoeMaterial(str(self.MeshNum), "")
		#material.setTexture('0')
		material.setDiffuseColor(NoeVec4([1.0, 1.0, 1.0, 0.0]))
		material.setDefaultBlend(0)
		self.matList.append(material)
		
		for MeshNum in range(0, len(self.meshInfoTmp)):
			if MeshNum != 0:
				if self.meshInfoTmp[MeshNum-1][0] % 2 != 0:
					VtxOffCurr += 0x8
					#UVOffCurr += 0x8
			self.bs.seek(VtxOffCurr, NOESEEK_ABS)
			vtxBuff = self.bs.readBytes(self.meshInfoTmp[MeshNum][0]*VtxBytes)
			rapi.rpgBindPositionBuffer(vtxBuff, noesis.RPGEODATA_FLOAT, VtxBytes, 0)
			#if VtxBytes > 0x16:
				#rapi.rpgBindNormalBuffer(vtxBuff, noesis.RPGEODATA_FLOAT, VtxBytes, 0xC)
			VtxOffCurr += self.meshInfoTmp[MeshNum][0]*VtxBytes
			
			self.bs.seek(UVOffCurr, NOESEEK_ABS)
			uvBuff = self.bs.readBytes(self.meshInfoTmp[MeshNum][0]*0x8)
			rapi.rpgBindUV1Buffer(uvBuff, noesis.RPGEODATA_FLOAT, 0x8)
			UVOffCurr += self.meshInfoTmp[MeshNum][0]*0x8
			
			self.bs.seek(self.meshInfoTmp[MeshNum][2], NOESEEK_ABS)
			edgeData = self.bs.readBytes(self.meshInfoTmp[MeshNum][3])
			edgeDecomp = rapi.decompressEdgeIndices(edgeData, self.meshInfoTmp[MeshNum][1])
			for i in range(0, self.meshInfoTmp[MeshNum][1]):
				t = edgeDecomp[i*2]
				edgeDecomp[i*2] = edgeDecomp[i*2 + 1]
				edgeDecomp[i*2 + 1] = t
			rapi.rpgCommitTriangles(edgeDecomp, noesis.RPGEODATA_USHORT, self.meshInfoTmp[MeshNum][1], noesis.RPGEO_TRIANGLE, 1)
		
		#if WeightOffCurr != 0:
				#self.bs.seek(WeightOffCurr, NOESEEK_ABS)
				#weightBuff = self.bs.readBytes(VtxNum*0x8)
				#rapi.rpgBindBoneIndexBuffer(weightBuff, noesis.RPGEODATA_BYTE, 4*fw.weightsPerVert, fw.weightsPerVert)
				#rapi.rpgBindBoneWeightBuffer(weightBuff, noesis.RPGEODATA_BYTE, 4*fw.weightsPerVert, fw.weightsPerVert)
		return
		
	def ValidateVtxNum(self, off2vtx):
		self.bs.seek(off2vtx, NOESEEK_ABS)
		VtxNumTrue = 0
		ID = self.bs.readByte()
		self.bs.seek(off2vtx, NOESEEK_ABS)
		for i in range(0, 0xFF):
			#self.bs.seek(0x14, NOESEEK_REL)
			Temp1 = self.bs.readByte()
			if Temp1 == ID:
				self.bs.seek(0x7, NOESEEK_REL)
				VtxNumTmp = self.bs.readShort()
				IdxNumTmp = self.bs.readShort()
				self.bs.seek(0x8, NOESEEK_REL)
				IdxOff = self.bs.readUInt()
				TempOff = self.bs.tell()
				self.bs.seek(IdxOff - 0x4, NOESEEK_REL)
				IdxOff = self.bs.tell()
				self.bs.seek(TempOff, NOESEEK_ABS)
				IdxSize = self.bs.readShort()
				meshInf = [VtxNumTmp, IdxNumTmp, IdxOff, IdxSize, ]
				self.meshInfoTmp.append(meshInf)
				VtxNumTrue += VtxNumTmp
				self.bs.seek(0x46, NOESEEK_REL)
			else:
				break
		#self.bs.seek(off2vtx, NOESEEK_ABS)
		return VtxNumTrue
		
	def FindSkeleton(self, filesize, offset):
		self.bs.seek(offset, NOESEEK_ABS)
		filesizeDiv4 = (filesize - offset)//4
		for i in range(0, filesizeDiv4-1):
			Temp = self.bs.readUInt()
			offTmp = self.bs.tell()
			if (Temp == 0x00010001):
				self.bs.seek(0x14, NOESEEK_REL)
				Temp = self.bs.readUInt()
				if (Temp == 0xFFFFFFFF):
					print('Skeleton data found at offset {}...'.format(hex(offTmp - 0x4)))
					self.Skeleton(offTmp - 0x4)
					break
				else:
					self.bs.seek(offTmp, NOESEEK_ABS)
		return
		
	def Skeleton(self, off2skel):
		self.bs.seek(off2skel, NOESEEK_ABS)
		self.bs.seek(0x4, NOESEEK_REL)
		BoneNum = self.bs.readInt()
		self.bs.seek(0x8, NOESEEK_REL)
		MatxOffCurr = self.bs.readInt()
		MatxOffCurr += self.bs.tell() - 0x4
		
		self.bs.seek(BoneNum*0x8, NOESEEK_REL)
		NameOffCurr = self.bs.tell()
		
		for i in range(0, BoneNum):
			self.bs.seek(NameOffCurr, NOESEEK_ABS)
			boneName = self.bs.readString()
			NameOffCurr += 0x38
			#self.bs.seek(MatxOffCurr, NOESEEK_ABS)
			BoneMatrix = [[1,0,0,0,], [0,1,0,0,], [0,0,1,0,], [0,0,0,1,],]       
			BoneMatrix = NoeMat44(BoneMatrix)
			"""for j in range(0, 4):
				Vec4 = NoeVec4.fromBytes(self.bs.readBytes(16))
				BoneMatrix[j] = Vec4"""
			BoneMatrix = BoneMatrix.toMat43()
			#MatxOffCurr += 0x40
			if i == 0:
				newBone = NoeBone(i, boneName, BoneMatrix, None, -1)
			else:
				newBone = NoeBone(i, boneName, BoneMatrix, None, 0)
			print(newBone)
			self.boneList.append(newBone)

		return

Аватара пользователя
Tosyk
Администратор
Сообщения: 1880
Зарегистрирован: 24 авг 2011, 03:11
Благодарил (а): 64 раза
Поблагодарили: 61 раз

Re: God Of War 3

#6 Сообщение Tosyk »

HaCKer_UTD, круто, спасибо. модельки открываются. а как ты текстуры высокого разрешения распаковывал?
При копировании материалов сайта ссылка на этот ресурс обязательна.
When copying materials from this site link to this resource is required.

HaCKer_UTD
Заинтересованный
Заинтересованный
Сообщения: 143
Зарегистрирован: 04 дек 2011, 15:25
Благодарил (а): 0
Поблагодарили: 0

Re: God Of War 3

#7 Сообщение HaCKer_UTD »

Да в модельках не везде UV будут корректны.


Код: Выделить всё

# God of War 3 texture extractor by maver1k_XVII

from inc_noesis import *
import noesis
import rapi
#import str

def registerNoesisTypes():
   handle = noesis.register("God of War 3 texture archive", ".ts")
   noesis.setHandlerTypeCheck(handle, noepyCheckType)
   noesis.setHandlerExtractArc(handle, GoW3ExtractArc) 
   #noesis.logPopup()
   return 1

#check if it's this type based on the data
def noepyCheckType(data):
   return 1       

headerOffsets = []
textureOffsets = []
textureNames = []

#load the archive
def GoW3ExtractArc(fileName, fileLen, justChecking):
  with open(fileName, "rb") as TS:
    ctx = rapi.rpgCreateContext()

    if justChecking:
       return 1

    WAD = NoeBitStream(rapi.loadPairedFile("God of War 3 model", ".wad"))
    WAD.setEndian(NOE_BIGENDIAN)
   
    texNum = 0

    fileSize = WAD.getSize()
    fileSizeDiv4 = fileSize//4
    for i in range(0, fileSizeDiv4-1):
       Temp = WAD.readInt()
       if Temp == 0x44445320: #1145328416:
          texNum = texNum+1
          headerOffsets.append(i*4)
          WAD.seek(headerOffsets[texNum-1]-16, NOESEEK_ABS)
          textureOffsets.append(WAD.readInt())
          WAD.seek(headerOffsets[texNum-1]+4, NOESEEK_ABS)     
    print('Texture number - {}'.format(texNum))         
    if texNum != 0:
      for i in range(0, texNum-2):
         if textureOffsets[i] != -1:
           WAD.seek(headerOffsets[i], NOESEEK_ABS)
           ddsHeader = WAD.readBytes(0x80)
           if textureOffsets[i+1] - textureOffsets[i] > 0:
             ddsImage = TS.read(textureOffsets[i+1] - textureOffsets[i])
           else:
             q = i + 1
             Temp = textureOffsets[i+1]
             while (Temp < 0) & (q < texNum - 1):
                  Temp = textureOffsets[q]
                  q = q + 1
             if Temp > 0:
               ddsImage = TS.read(Temp - textureOffsets[i])
             else:
               ddsImage = TS.read(fileLen - textureOffsets[i])
           rapi.exportArchiveFile('{}.dds'.format(i), ddsHeader+ddsImage)

    rapi.rpgClearBufferBinds() 

  return 1

Аватара пользователя
Tosyk
Администратор
Сообщения: 1880
Зарегистрирован: 24 авг 2011, 03:11
Благодарил (а): 64 раза
Поблагодарили: 61 раз

Re: God Of War 3

#8 Сообщение Tosyk »

спс. а поправить руками uv реально?
а кости реально вытащить?
При копировании материалов сайта ссылка на этот ресурс обязательна.
When copying materials from this site link to this resource is required.

HaCKer_UTD
Заинтересованный
Заинтересованный
Сообщения: 143
Зарегистрирован: 04 дек 2011, 15:25
Благодарил (а): 0
Поблагодарили: 0

Re: God Of War 3

#9 Сообщение HaCKer_UTD »

Tosyk писал(а):спс. а поправить руками uv реально?
а кости реально вытащить?

Реально, но долго. Нужно долго копаться в hex редакторе и анализировать данные.
С костями не знаю, но списки костей там есть.

Ответить

Вернуться в «Персонажи (characters)»