Mod Tool/Scripting: Difference between revisions

From OniGalore
Jump to navigation Jump to search
(scanning the mountain compound AKEV xml for textures takes about 20 secs for me, reading the oni file directly takes just 1 second)
(get OS bit version)
Line 1: Line 1:
===OS bit version===
'''shorter but slower'''
if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then
logmessage "run 64-bit OS"
else
logmessage "run 32-bit OS"
end if
'''longer but faster'''
    Const HKEY_LOCAL_MACHINE = &H80000002
    Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    strKeyPath = "HARDWARE\DESCRIPTION\System\CentralProcessor\0"
    strValueName = "Identifier"
    oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue   
    if (InStr(strValue, "x86")) then
        logmessage "32"
    else
        logmessage "64"
    end If
===Math===
===Math===
====Euler rotation -> matrix====  
====Euler rotation -> matrix====  

Revision as of 20:54, 6 September 2014

OS bit version

shorter but slower

if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then
	logmessage "run 64-bit OS"
else
	logmessage "run 32-bit OS"
end if

longer but faster

   Const HKEY_LOCAL_MACHINE = &H80000002
   Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
   strKeyPath = "HARDWARE\DESCRIPTION\System\CentralProcessor\0"
   strValueName = "Identifier"
   oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue    
   if (InStr(strValue, "x86")) then
       logmessage "32"
   else
       logmessage "64"
   end If


Math

Euler rotation -> matrix

function cosn (n)
	cosn = cos(XSIMath.DegreesToRadians(n))
end function
function sinn (n)
	sinn = sin(XSIMath.DegreesToRadians(n))
end function

' ################
logmessage "input"
x = 60 : logmessage x
y = 60 : logmessage y
z = 60 : logmessage z

logmessage "##################"
logmessage "converted"

set RotMatX = XSIMath.CreateMatrix3(1, 0, 0, 0, cosn(x), sinn(x), 0, -sinn(x), cosn(x))
set RotMatY = XSIMath.CreateMatrix3(cosn(y), 0, -sinn(y), 0, 1, 0, sinn(y), 0, cosn(y))
set RotMatZ = XSIMath.CreateMatrix3(cosn(z), sinn(z), 0, -sinn(z), cosn(z), 0, 0, 0, 1)

RotMatZ.MulInPlace RotMatY
RotMatZ.MulInPlace RotMatX

for i=0 to 2
	for j=0 to 2
		logmessage RotMatZ (i, j)
	next
next 

' INFO : input
' INFO : 60
' INFO : 60
' INFO : 60
' INFO : ##################
' INFO : converted
' INFO : 0,25
' INFO : 0,808012701892219
' INFO : 0,53349364905389
' INFO : -0,433012701892219
' INFO : -0,399519052838329
' INFO : 0,808012701892219
' INFO : 0,866025403784439
' INFO : -0,433012701892219
' INFO : 0,25


Matrix -> Euler rotation

Function Atan2(y, x)
  If x > 0 Then
    Atan2 = Atn(y / x)
  ElseIf x < 0 Then
    Atan2 = Sgn(y) * (XSIMath.PI - Atn(Abs(y / x)))
  ElseIf y = 0 Then
    Atan2 = 0
  Else
    Atan2 = Sgn(y) * XSIMath.PI / 2
  End If
End Function


function ToEuler(M00, M10, M20, M21, M22)
            a = M00
            b = M10
            dim c, s, r

            if b = 0 then
                c = Sgn(a)
                s = 0
                r = Abs(a)

            elseif a = 0 then
                c = 0
                s = Sgn(b)
                r = Abs(b)
                
            elseif Abs(b) > Abs(a) then
                t = a / b
                u = Sgn(b) * Sqr(1 + t * t)
                s = 1 / u
                c = s * t
                r = b * u

            else
                t = b / a
                u = Sgn(a) * Sqr(1 + t * t)
                c = 1 / u
                s = c * t
                r = a * u

	    end if

            Z = -Atan2(s, c)
            Y = Atan2(M20, r)
            X = -Atan2(M21, M22)

	    X = XSIMath.RadiansToDegrees(X)
	    Y = XSIMath.RadiansToDegrees(Y)
	    Z = XSIMath.RadiansToDegrees(Z)

	    ToEuler = array(X, Y, Z)
end function

' ################################
set RotMat = XSIMath.CreateMatrix3( _
		0.25, 0.808012701892219, 0.53349364905389, _
		-0.433012701892219, -0.399519052838329, 0.808012701892219, _
		0.866025403784439, -0.433012701892219, 0.25 )


' convert matrix to euler rotation and store values to array
ReXYZ = ToEuler(RotMat(0,0), RotMat(1,0), RotMat(2,0), RotMat(2,1), RotMat(2,2))

logmessage "reconverted"
logmessage ReXYZ(0)
logmessage ReXYZ(1)
logmessage ReXYZ(2)

' INFO : 60
' INFO : 60
' INFO : 60


Euler rotation -> quaternion

dim x, y, z, dRotation, qRotation
x = 90
y = 0
z = 0

set dRotation = XSIMath.CreateRotation(XSIMath.DegreesToRadians(x), XSIMath.DegreesToRadians(y), XSIMath.DegreesToRadians(z)) 
set qRotation = XSIMath.CreateQuaternion() 

	dRotation.GetQuaternion (qRotation) 
	LogMessage qRotation.W
	LogMessage qRotation.X
	LogMessage qRotation.Y
	LogMessage qRotation.Z
	' INFO : 0,707106781186548
	' INFO : 0,707106781186547
	' INFO : 0
	' INFO : 0

' to calculate oni quaternions from euler rotations use this setup:
' 	LogMessage qRotation.X
'	LogMessage qRotation.Y
'	LogMessage qRotation.Z
'	LogMessage qRotation.W * -1


Quaternion -> Euler rotation

dim qW, qX, qY, qZ, qRotation, x, y, z

	qW = 0.707106781186548
	qX = 0.707106781186547
	qY = 0
	qZ = 0

set qRotation = XSIMath.CreateQuaternion (qW, qX , qY, qZ)

	qRotation.GetXYZAngleValues x, y, z
	logmessage XSIMath.RadiansToDegrees(x)
	logmessage XSIMath.RadiansToDegrees(y)
	logmessage XSIMath.RadiansToDegrees(z)
	' INFO : 89,9999999999999
	' INFO : 0
	' INFO : 0

' to calculate euler rotations from oni quaternions use this setup:
	'qX = ...
	'qY = ...
	'qZ = ...
	'qW = ... * -1
'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ)


read file

as binary

scan_AKEV_file_table

sub scan_AKEV_file_table
	' ##############################################
	OniInputFile =  "H:\Oni\AE\GameDataFolder\level1_Final\AKEVEnvWarehouse.oni"
	' ##############################################
    
	Set OniInputFileStream = CreateObject("ADODB.Stream")
	OniInputFileStream.Type = 1
	OniInputFileStream.Open
	OniInputFileStream.LoadFromFile OniInputFile

	' ### read AKEV textures table offset and size
	ByteNum = 4
	' ##############################################
	TOffset = cLng("&H" & "28")
	' ##############################################
	OniInputFileStream.Position = TOffset
	BArr1 = OniInputFileStream.Read(ByteNum)

	ByteNum = 4
	' ##############################################
	TSize = cLng ("&H" & "2C")
	' ##############################################
	OniInputFileStream.Position = TSize
	BArr2 = OniInputFileStream.Read(ByteNum)


	' ### get AKEV textures table offset and size
	TOffsetHex = SimpleBinaryToString(BArr1)
	for i = ubound(TOffsetHex ) - 1 to 0 step -1
		newhex = newhex & hex(Asc(TOffsetHex(i)))
	next
	logmessage newhex
	logmessage "name table offset: " & cLng("&H" & newhex)
	TOffsetInt = cLng("&H" & newhex)
	newhex = ""
	
	TSizeHex = SimpleBinaryToString(BArr2)
	for i = ubound(TSizeHex) - 1 to 0 step -1
		newhex = newhex & hex(Asc(TSizeHex(i)))
	next
	logmessage newhex
	logmessage "name table size: " & cLng("&H" & newhex)
	TSizeInt = cLng("&H" & newhex) 
	
  	logmessage "------------------------------"
  	

	' ### read table content
	ByteNum = TSizeInt
	OniInputFileStream.Position = TOffsetInt
	BArr3 = OniInputFileStream.Read(ByteNum)
	TContent = SimpleBinaryToString(BArr3)
	
	' ### name grapper
	NG = ""
	for each n in TContent
		if not Asc(n) = 0 then
			NG = NG & n
		else
			'if instr(NG, "TXMP") = 1 then
				' write TXMP to array ?
				logmessage NG
			'end if
			NG = ""
		end if
	next
end sub

Function SimpleBinaryToString(Binary)
	ReDim tmpArr(LenB(Binary) - 1)
	For I = 1 To LenB(Binary)
		S = Chr(AscB(MidB(Binary, I, 1)))
		tmpArr(I - 1) = S
	Next
	SimpleBinaryToString = tmpArr
End Function

Output:

' INFO : 0E40
' INFO : name table offset: 3648
' INFO : 0A4A
' INFO : name table size: 2634
' INFO : ------------------------------
' INFO : AKEVEnvWarehouse
' INFO : AGDBEnvWarehouse
' INFO : TXMP_DOOR_FRAME
' INFO : TXMPNONE
' INFO : TXMPSUMI_1
' INFO : TXMPTC_CONTROL_01
' [...]
' INFO : TXMPWH_DCTRBND