Jump to content

Spectral Paladin

Fedaykin
  • Posts

    968
  • Joined

  • Last visited

Reputation

16 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Yup saw the tweet the other day and have been meaning to applaud the decision! I have been endeavoring towards a similar goal, but thankfully in another genre so there will be no competition between us I will be following your progress closely!
  2. So by the way, the girl in the video I linked above is hyping it up by making some sort of Dune reading club over the summer, as well as selling her own collector's edition of it. Some details here: https://youtu.be/7cHHTrRjghc?t=14m20s and on a previous vid of hers. I'm not affiliated in any way
  3. Yup, Unity is solid. It's always good to see something dune-related, particularly to do with Emperor. Don't hesitate to post news/updates around these forums
  4. Hello - yes, sure. It looks like I was distracted by other things during the holidays. Below is the latest version of it, I believe. It takes one command line argument, the name of an xbf file, and produces an obj file with the same name (only extension differs), with the name of the objects, their vertices and faces. All vertices are exported with their coordinates transformed; hence the use of the Numpy library. #!/usr/bin/env python3 import struct import numpy as np import argparse import os def readInt(file): return struct.unpack("<i", file.read(4))[0] def readUInt(file): return struct.unpack("<I", file.read(4))[0] def readInt16(file): return struct.unpack("<h", file.read(2))[0] def readUInt16(file): return struct.unpack("<H", file.read(2))[0] def readMatrix(file): return struct.unpack("<16d", file.read(8*16)) def readByte(file): return struct.unpack("<c", file.read(1))[0] class Vertex: def __init__(self): self.vertices = None def readFrom(self, file): self.vertices = struct.unpack("<6f", xbfFile.read(4 * 6)) class Face: def __init__(self): self.longs = [] self.floats = [] def readFrom(self, file): self.longs = struct.unpack("<5i", xbfFile.read(4 * 5)) self.floats = struct.unpack("<6f", xbfFile.read(4 * 6)) VertexTotal = 0 #for writing out to obj class Object: def __init__(self): self.children = [] self.vertices = [] self.faces = [] def readFrom(self, file): vertexCount = readInt(file) flags = readInt(file) hasPrelight = bool(flags & 1) hasFaceData = bool(flags & 2) hasVertexAnimation = bool(flags & 4) hasKeyAnimation = bool(flags & 8) faceCount = readInt(file) childCount = readInt(file) self.transform = readMatrix(file) nameLength = readInt(file) self.name = file.read(nameLength) for i in range(childCount): child = Object() child.readFrom(file) self.children.append(child) for i in range(vertexCount): vertex = Vertex() vertex.readFrom(file) self.vertices.append(vertex) for i in range(faceCount): face = Face() face.readFrom(file) self.faces.append(face) if hasPrelight: rgb = [readInt(file) for i in range(vertexCount)] if hasFaceData: faceData = [readInt(file) for i in range(faceCount)] if hasVertexAnimation: frameCount = readInt(file) count = readInt(file) actual = readInt(file) keyList = [readUInt(file) for i in range(actual)] if count < 0: #compressed scale = readUInt(file) compCount = readUInt(file) compressedData = [readUInt16(file) for i in range(compCount*4)] if (scale & 0x80000000): #interpolated interpolationData = [readUInt(file) for i in range(frameCount)] if hasKeyAnimation: frameCount = readInt(file) keynimationflags = readInt(file) actual = readInt(file) for i in range(frameCount+1): readInt16(file) for i in range(actual): struct.unpack("<12f", file.read(4 * 12)) def writeToObj(self, file, transform=None, resetTotal=True): global VertexTotal if resetTotal: VertexTotal = 0 np_transform = np.array(self.transform) np_transform.shape=(4,4) if transform is not None: np_transform = np_transform.dot(transform) name = self.name.decode() file.write("o "+name+"\n") for vertex in self.vertices: np_point = np.array([vertex.vertices[0], vertex.vertices[1], vertex.vertices[2], 1]) np_result = np_point.dot(np_transform) file.write("v "+str(np_result[0])+" "+str(np_result[1])+" "+str(np_result[2])+" "+str(np_result[3])+"\n") file.write("\n") for face in self.faces: file.write("f "+str(face.longs[0]+1+VertexTotal)+" "+str(face.longs[1]+1+VertexTotal)+" "+str(face.longs[2]+1+VertexTotal)+"\n") file.write("\n") VertexTotal += len(self.vertices) for child in self.children: child.writeToObj(file, np_transform, False) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("file") args = parser.parse_args() with open(args.file, "rb") as xbfFile: version = readInt(xbfFile) appDataSize = readInt(xbfFile) xbfFile.read(appDataSize) textureNameDataSize = readInt(xbfFile) xbfFile.read(textureNameDataSize) xbfObject = Object() xbfObject.readFrom(xbfFile) xbfname = os.path.splitext(args.file)[0] with open(xbfname+".obj", "w") as f: xbfObject.writeToObj(f) Some of the types read may not be strictly correct (i.e. int vs uint). I will have to re-immerse myself in the project to ensure I'm not forgetting something already worked out. What prompts your interest? Have you modded Emperor or other Westwood games before? Is there something you are working on at the moment?
  5. The engine in C&C3 (SAGE) has nothing to do with the E:BFD engine. I have seen around a misconception that the latter was a precursor to former, but it is incorrect.
  6. A dust scout in Blender: Note the object list in the top right - this is the object tree from the xbf file (but flattened).
  7. December 15th marked 15 years since posting the topic “Emperor expansion pack” in Westwood's forums, the project which became known as the pioneering Kwisatz Haderach mod. I was very young then and not very mature and fled before it was all completed. One thing that got to me was having to watch helpless as others tried to crack the XBF format, the key to the models and so to a true expansion pack. This left me with the wish to return to the task numerous times, as my own computing skills increased. I have not really uncovered any more information than what was known back in 2002-03, which was already quite a lot actually. However, I believe that the viewer/exporter which was the product of those efforts has vast room for improvement. What follows is an outline of goals that in my opinion will conclusively resolve the XBF challenge - even though this will come 10+ years too late. Primary Goal A: Obj importer/exporter The obj format is virtually universal among 3D software - pretty much any of them can read it and many can export it. Thus converting to/from it opens up many possibilities to work with the models' geometry. The only caveat is that animations are not supported. What I propose and have worked on is a set of Python scripts that serve as command-line tools to import and export to this format. It is quick to develop in Python and the code can be easily adjusted. Specifically the goal can further be broken down into: • From XBF to obj - geometry only. This is complete (see screenshot below). I am happy to share the script after some cleaning up of the code. • From obj to XBF - the mirror image of the above. It is sufficient to add an equivalent write() for each read() • Texture support Primary Goal B: Collada importer/exporter Collada is a format created for the express purpose of sharing files across incompatible 3D software. The advantage over obj is support for animation. Thus, all Python scripts above should graduate to converting from/to Collada. Secondary goals/other possibilities Rather than convert to obj/collada, many 3D software tools allow the creation of plugins to support a format. In the case of Blender for example, these are written in Python and so it should be relatively simple to borrow code from the scripts above. Nonetheless, this is not a priority since pretty much any tool can work with obj and collada. It is also possible to write a viewer/editor specifically for XBF. The sole reason to do this is a better chance to fill out the last gaps in understanding the format. Otherwise, it is a waste of effort to reinvent the wheel. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On the off chance someone has shared a similar fixation with XBF throughout the years, it would be fantastic if you would like to post about your progress so that efforts can be combined. I am very open to sharing my own code on a public repository, assuming there is interest. Though it would hardly be a surprise if everyone has long moved on.
  8. Sure, that would be interesting and informative. Just be sure not to share your secrets
  9. Just ran it through an emboss filter because I had grown tired of its color Sure am, of course. Could likely do a far better job with your ideas nowadays too But first things first: the screenie is viewing a xbf file from E:BFD, a job which the community never finished. A 15-year itch
  10. That looks pretty neat! Interesting, I knew that about E:BFD, but not dune2k. If you don't mind going on a tangent here, do you have any experience with the E:BFD files? Do you know if there's any overlap in their practices, in particular any insights into their formats that could be useful in Emperor?
  11. You mean like gameheaven? *playing around innocently*
  12. someone on youtube saying it was actually big news yesterday(?), but with no more details or evidence that anything is actually in the works, just more speculation: https://youtu.be/MDtTIKEWYTU?t=2m49s
  13. Not even concerned as much by Trump himself as much as his administration the attitudes that this result has validated
  14. Very happy to see that you have picked this up again (have been feeling guilty ever since evangelizing C++/SFML and the whole thing petered out!)
  15. *still hopes to make Kwisatz Haderach 3 one day*
×
×
  • Create New...