Talk:Mod Tool/OniTools addon: Difference between revisions
Paradox-01 (talk | contribs) m (working on ghost quads management again, today: heights) |
Paradox-01 (talk | contribs) m (heights of multiple GQs editable, now also compatible with onisplit-generated ones) |
||
Line 19: | Line 19: | ||
! env markers | ! env markers | ||
! furniture | ! furniture | ||
! ghost quads | |||
<!-- ! particles --> | <!-- ! particles --> | ||
! triggers | ! triggers | ||
Line 30: | Line 31: | ||
| x | | x | ||
| x | | x | ||
| - | |||
<!-- | --> | <!-- | --> | ||
| x | | x | ||
Line 42: | Line 44: | ||
<!-- | --> | <!-- | --> | ||
| | | | ||
| - | |||
| [https://dl.dropboxusercontent.com/u/139715/OniGalore/ModToolScript/LevelBuilder/HelpFunctions.vbs x] | | [https://dl.dropboxusercontent.com/u/139715/OniGalore/ModToolScript/LevelBuilder/HelpFunctions.vbs x] | ||
| [https://dl.dropboxusercontent.com/u/139715/OniGalore/ModToolScript/LevelBuilder/HelpFunctions.vbs x] | | [https://dl.dropboxusercontent.com/u/139715/OniGalore/ModToolScript/LevelBuilder/HelpFunctions.vbs x] | ||
Line 53: | Line 56: | ||
| | | | ||
| | | | ||
| - | |||
| | | | ||
| | | | ||
Line 60: | Line 64: | ||
|- | |- | ||
| preview imgs | | preview imgs | ||
| | | x | ||
| | | | ||
| | | | ||
| | | | ||
| x | | x | ||
| - | |||
| | |||
<!-- | --> | <!-- | --> | ||
| [https://dl.dropboxusercontent.com/u/139715/OniGalore/VanillaTURRs.jpg x] | | [https://dl.dropboxusercontent.com/u/139715/OniGalore/VanillaTURRs.jpg x] | ||
| x | | x | ||
Line 76: | Line 81: | ||
| | | | ||
| | | | ||
| - | |||
<!-- | --> | <!-- | --> | ||
| | | | ||
Line 87: | Line 93: | ||
| | | | ||
| | | | ||
| x | |||
<!-- | --> | <!-- | --> | ||
| | | | ||
Line 98: | Line 105: | ||
| | | | ||
| | | | ||
| x | |||
<!-- | --> | <!-- | --> | ||
| | | | ||
Line 104: | Line 112: | ||
|- | |- | ||
| save in project | | save in project | ||
| | |||
| | | | ||
| | | | ||
Line 115: | Line 124: | ||
|- | |- | ||
| PrjToXml | | PrjToXml | ||
| | |||
| | | | ||
| | | | ||
Line 128: | Line 138: | ||
more ... later | more ... later | ||
powerups, flags, tvs, crsa,... | |||
Download link should only provided if Oni retail installation is found on client machine. | Download link should only provided if Oni retail installation is found on client machine. |
Revision as of 19:56, 27 April 2016
Note to self:
- I must merge this with http://wiki.oni2.net/Talk:Mod_Tool
- and clean up notes that are out-of-date
- --paradox-01 (talk) 21:27, 16 July 2014 (CEST)
Dev notes for the remake
New code snippets
Latest MT addon attempt. Reducing complexity by dropping support for adding AE resources. Vanilla material only.
Scratching together...
- | characters | consoles | doors | env markers | furniture | ghost quads | triggers | turrets | weapons |
---|---|---|---|---|---|---|---|---|---|
shared (collection) | x | x | x | x | - | x | x | x | |
OniToDae + Html | - | x | x | ||||||
preview imgs | x | x | - | x | x | ||||
DnD recognition | - | x | |||||||
layer support | x | x | |||||||
PPG interface | x | ||||||||
save in project | |||||||||
PrjToXml |
more ... later
powerups, flags, tvs, crsa,...
Download link should only provided if Oni retail installation is found on client machine.
Editing simultaneously multiple ghost quads heights
Onisplit-generated ghost quads vertex ids can differ sometimes. So before changing multiple ghosts in height, their lowest and highest points must be identified.
Display flag via ICE
Using a "Simulate Rigid Bodies" ICETree node for this is overkill. But it works and I fail to come up with alternatives, so...
'### setup flag display by abusing ICE CreatePrim "Cube", "MeshSurface" ApplyOp "ICETree", selection(0), siNode, , , 0 AddICENode "$XSI_DSPRESETS\ICENodes\SimulateRigidBodiesNode.Preset", selection(0) & ".polymsh.ICETree" ConnectICENodes selection(0) & ".polymsh.ICETree.port1", selection(0) & ".polymsh.ICETree.SimulateRigidBodies.simulate" AddICENode "$XSI_DSPRESETS\ICENodes\IntegerNode.Preset", selection(0) & ".polymsh.ICETree" ConnectICENodes selection(0) & ".polymsh.ICETree.SimulateRigidBodies.precision", selection(0) & ".polymsh.ICETree.IntegerNode.result" DisplayPortValues selection(0) & ".polymsh.ICETree.SimulateRigidBodies.precision" SetValue selection(0) & ".polymsh.ICETree.IntegerNode.value", 7 SaveKey selection(0) & ".polymsh.ICETree.IntegerNode.value", 1
'### check if ICETree op exist on this object for each oOperator in selection(0).ActivePrimitive.ConstructionHistory if oOperator.Name = "ICETree" then got_ICE = 1 end if Next if got_ICE then logmessage "found ICETree" else logmessage "couldn't find ICETree" end if
More wild ideas
Animated reference
Every step on the timeline triggers an event, namely siOnTimeChangeEvent.
It could be used to exchange an the image of an object.
This could be either good for an animated textures (BINA3RAPd*.oni) or for an animated reference for TRAM creation.
Strategy:
- Making a folder named "Animated_Ref".
- Drag and drop the folder into Mod Tool.
- A grid becomes created on a new layer "Animated_Ref". Selection disabled.
- Mod Tool gets then the first image and looks for the pixels.
- Based on that pixels the grids becomes deformed to match the image's proportions.
- Then this "Animated_Ref" grid should be ready for usage.
Similar can be done with the Rotoscope.
Something like that:
function siOnTimeChangeEvent_OnEvent( in_ctxt ) ' fixed code 'SetValue "Views.ViewD.RightCamera.camdisp.rotoenable", True 'SetValue "Views.ViewD.RightCamera.rotoscope.imagename", "Clips.Animated_Ref_N_jpg" ' flexible code ' find active viewport, set Rotoscope active and choose image 'SetValue GetViewCamera(GetViewIndex) & ".camdisp.rotoenable", True 'SetValue GetViewCamera(GetViewIndex) & ".rotoscope.imagename", "Clips.Animated_Ref_N_jpg" current_frame = cstr(in_ctxt.GetAttribute("Frame")) if GetValue(GetViewCamera(GetViewIndex) & ".camdisp.rotoenable") = true then ' Animated_Ref_60.jpg ' . becomes _ SetValue GetViewCamera(GetViewIndex) & ".rotoscope.imagename", "Clips.Animated_Ref_" & current_frame & "_jpg" end if siOnTimeChangeEvent_OnEvent = true end function
New camera animations
last frame of OBANOutroCam02 |
There's already an excel macro available but now I want to build cam anims without excel.
The last frame's rotation of level1_Final file OBANOutroCam02 is: -0.0158410165 0.854542 0.0261086561 -0.518483639.
Those quaternions are sorted in X Y Z -W order, so we've to watch out a bit when setting the input for converting them to euler rotations in degrees.
If a newly created object (in this case a cube) shall serve as camera placeholder then the X output has to be multiplied by -1 and the Y output has to be reduced by -180. Those changes must repeated again when exporting the object's rotation to xml.
Update: Sept. 29, 2012
If camera is a real one then the additional X and Y changes aren't necessary. (Primitive > Camera > any should do)
Positions and rotations keyframes can be applied to the camera root object.
Adding multiple textures to level geometry [out-dated]
Material and textures are normally stored right under the object. But AKEV geometry can have more than one texture. Here comes polygon clusters in to play.
An example:
set oCube = Application.ActiveProject.ActiveScene.Root.AddGeometry("Cube","MeshSurface") SelectObj "cube", , True SelectGeometryComponents "cube.poly[LAST]" CreateCluster AddToCluster "cube.polymsh.cls.Polygon, cube.poly[2-4]" RemoveFromCluster "cube.polymsh.cls.Polygon, cube.poly[3]"
The cube has now a polygon cluster. More can be added. Each cluster must get its own material before a texture can be applied to the desired polygons.
[...]
TRBS-fitting TRMA creation
With the following code ...
One more idea is to add support for reflective textures.
|
hexhound hierarchy |
if selection.count > 0 then ' any part could be selected, let's find the root body part SelectNeighborObj selection(0), 4 ' get all members including the pelvis set bodyparts = selection(0).FindChildren( , , siMeshFamily) for each member in bodyparts logmessage "object name: " & member.name if not typename(member.Material.CurrentImageClip) = "Nothing" then logmessage "texture: " & member.Material.CurrentImageClip.source.filename.value 'logmessage "material: " & member.Material.name 'logmessage "shader: " & member.Material.shaders(0).name logmessage "X: " & member.Material.CurrentImageClip.source.Parameters("XRes").Value logmessage "Y: " & member.Material.CurrentImageClip.source.Parameters("YRes").Value end if logmessage "----------------------------------------------------------" next logmessage "counted body parts: " & bodyparts.count else logmessage "no object was selected" end if
' INFO : object name: A ' INFO : texture: C:\Users\RRM\Desktop\A.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: R ' INFO : texture: C:\Users\RRM\Desktop\R.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: S ' INFO : texture: C:\Users\RRM\Desktop\S.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: P ' INFO : texture: C:\Users\RRM\Desktop\P.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: Q ' INFO : texture: C:\Users\RRM\Desktop\Q.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: N ' INFO : texture: C:\Users\RRM\Desktop\N.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: O ' INFO : texture: C:\Users\RRM\Desktop\O.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: L ' INFO : texture: C:\Users\RRM\Desktop\L.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: M ' INFO : texture: C:\Users\RRM\Desktop\M.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: B ' INFO : texture: C:\Users\RRM\Desktop\B.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: C ' INFO : texture: C:\Users\RRM\Desktop\C.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: D ' INFO : texture: C:\Users\RRM\Desktop\D.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: E ' INFO : texture: C:\Users\RRM\Desktop\E.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: F ' INFO : texture: C:\Users\RRM\Desktop\F.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: G ' INFO : texture: C:\Users\RRM\Desktop\G.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: H ' INFO : texture: C:\Users\RRM\Desktop\H.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: I ' INFO : texture: C:\Users\RRM\Desktop\I.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: J ' INFO : texture: C:\Users\RRM\Desktop\J.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : object name: K ' INFO : texture: C:\Users\RRM\Desktop\K.tga ' INFO : X: 512 ' INFO : Y: 512 ' INFO : ---------------------------------------------------------- ' INFO : counted body parts: 19
Canceled
Reimporting and recovering of original vertex shading on doors, consoles, etc.
- Q: Can we reimport and recover such data?
- A: XML-based AKEV editing isn't possible. But editing the binary file is possible.
- However, OniSplit cannot easily reapply original vertex shading since the used M3GMs have different vertex ids.
Old notes from realization attempt:
- import a console into Mod Tool
- associate an ID (and everything else necessary to build the "BINACJBOconsole.xml" file later)
- apply vertex shading
- hit level export button to build the BINACJBOconsole and other xml and eventully all level files as onis
- now it would be time for the binary AKEV patching
- console id can be used to identify the polygons in AKEV's AGQG instance where the vertex shading is stored (<Colors>)
- now we have to hope that onisplit imported the mesh's polygons in the same order as Mod Tool read the polygons
- getting the vertex color from Mod Tool: there's already a code piece on MT's page ("[42] get vertex color")
I'm not fluent with binary stuff so I will dump some notes here:
Data table
Reading the AKEV's name table was more or less easy. This time we need to look up the data table.
Three things to take care about: reading hex numbers backwards (as usual in Oni), adding relative offsets to data table's offset (took a pretty while to find that one out*), subtracting 8 bytes for no other reason to get the correct offset.
- * Regarding binary information I found THAT page very useful.
What AKEV data do we need? The structure is fixed, so actually only the size or the item count is needed to pin down all colors.
- data table offset at 0x20
- AGQG offset (A) at 0x94
- AGQG size (B) at 0x9C
- AGQG items at 0x20 + A + 0x1C - 8
- AGQG start at 0x20 + A - 8
- AGQG end at 0x20 + A + B - 8
Color data in AGQG
The byte array is like this: BF BF BF FF (191 191 191 255 = grey).
The format is BGRA whereby I couldn't see Alpha to have an effect on the color strength. Maybe it will be different with a texture (not tested yet).
AGQG reader
https://dl.dropboxusercontent.com/u/139715/OniGalore/temp/AKEV_AGQG_reader.txt
output sample:
' INFO : 000280 ' INFO : data table offset: 640 ' INFO : 0004A8 ' INFO : AGQG table offset: 1192 ' INFO : 0001E0 ' INFO : AGQG table size: 480 ' INFO : ------------------------------ ' INFO : AGQG_start: 1824 ' INFO : ------------------------------ ' INFO : AGQG array size: 8 ' INFO : ---------- ' INFO : element: 1 ' INFO : 00000000 ' INFO : 01000000 ' INFO : 02000000 ' INFO : 03000000 ' INFO : 00000000 ' INFO : 00000000 ' INFO : 00000000 ' INFO : 00000000 ' INFO : BFBFBFFF (color: 191 191 191 255) ' INFO : BFBFBFFF (color: 191 191 191 255) ' INFO : BFBFBFFF (color: 191 191 191 255) ' INFO : BFBFBFFF (color: 191 191 191 255) ' INFO : 00000804 ' INFO : FFFFFFFF (object id: -1) ' INFO : ---------- ' INFO : [...]
Complications
M3GM files use triangles while AGQG instances use quads (look, there are always 4 points each with its own 32-bit color slot).
That means Onisplit converts the M3GM triangles into quads on import.
So Mod Tool would need to exactly mimic OniSplit's way turning triangles into quads.
This information is based on following experience:
- Console0 triangles = 94
- After triangle-to-quad conversion.
- Console0: 47 quads = 38 (main) + 6 (collision box) + 1 + 1 + 1 (light tex quads)
- AGQG has 47 elements.
Failed on:
- read the AKEV xml file to get the mesh's vertices/quads (slow and uncool)
- extract the mesh as dae from AKEV and use that as vertex shading object (reference for M3GM) (faster but uncool because it still requires all consoles, doors, etc.)
AKEV data and extracted console mesh have different polygon IDs and point IDs. Identifying each point by position (taking tolerances into account) and then identifing the quads and triangles would take too long. So, it's still possible but at the moment it's a black hole consuming too much dev time... Darn.