Quantcast
They better take the tournament, they knocked out Portugal those bastards

My name is Michael Kofman and
I am a Developer.

Graduated Full Sail University with a Bachelors of Science in Game Development with a life long background in IT and Web Design.



Page 2 of 14123...Last »


15
February
2009

My Full Sail Experience

What drove me to take the plunge?

After high school I was very frustrated by the core classes that defined the first two years of a regular University. I was becoming even more frustrated by the partying, and lack of vision most of my friends and peers were only concerned about. I don’t remember what conversation made me remember Full Sail but it was a school I had known about since middle school and I truly felt my passion was in game development. I decided that I want two things out of my career. First interesting and challenging work that would keep me ever interested. Second I wanted to work at a fun place that allowed for creativity. So long story made a little shorter, Full Sail University is one of two schools at the time that might hope to provide for the sort of education that really teaches you the internal workings of making a game. I took the plunge. I packed up everything I owned into my car at the time 1998 Nissan Maxima, and drove it from Philadelphia to Winter Park FL. Thankfully my apartment was ready; I choose to stay at Winter Park Pointe apartments because they were the closest and cheapest in the area. I also decided to not have a roommate after a few disappointing attempts. So for the next few months I slept on nothing but a mattress.

The first three months are crucial at Full Sail; they help separate those who can and cannot handle the program. Odd schedules that have classes end at 1am and start again at 9am the next day. It was interesting trying to adapt to it, and many of us became nocturnal. The next month the schedule changed again. Oh yes, a semester is only a month long and classes are 40 hours a week. The pacing was perfect for me and I really dug all the knowledge. I was excited to be there, and I was just amazed at the different types of people I was surrounded by and all of whom held a strong interest in video games. I bought a PS3, and started playing games a lot more than ever before in my life. At some point along the way I think I lost sight of my goal and what was at stake. After the first three months I felt like I had C++ down solid.

The rest of the year we spent learning MFC, Win32, C#, DirectX, and Design Patterns. Along the way we also had a few general education classes needed for accreditation, but they too were all geared towards Game Development. This included an English course that had us write a full game design document. Math in Linear Algebra, Calculus, and Physics all laid out the foundation for what was to come.

The first game making experience was defined by two classes; Software Game Development and Software Game Production. I feel like both experiences deserve a post mortem but the lessons learned cannot be learned from reading this.

After the half way point it felt like we did something really great. We made a game! A great one at that. I, Casey Flach, and Charlie Prouse put together a 3D top down shooter in a roughly five weeks. Who knew that making a game doesn’t take months but weeks? Well we were hungry for more knowledge and the next few months more than helped satisfy that appetite. We took classes in Artificial Intelligence, Networking, Machine Architecture, OpenGL, Optimization, and Engine Development.

And we finally made it … final project… to be continued….

No Comments »



15
February
2009

Working with Unity3D

Unity 3D has been a really great experience at my new job at Zeitgeist Games. Although I’m under NDA and can’t talk about what I’ve really been working on, I decided it would be a good idea to share with you a learning demo I put together that demonstrates the capabilities of Unity3D in a browser.

Take a look and I hope you like this Unity3D Particle Demo.

No Comments »



12
August
2008

Exoporting from Maya

Game developers, big and small, are often tasked with content generation. We write tools that range from scripters, effects editors, to the infamous level editors. While level editors serve an important role in the game development cycle, sometimes time and limited man power don’t allow for the creation of a fully featured environment.

In this tutorial we’ll go straight to the source with the creation of our Maya exporter. We will not be covering Mel, or building our own GUI. Instead we’ll be adopting from the MPxFileTranslator, a maya file exporter. We’ll be saving out our code into an XML file format that can then be used as input for character models, or even levels.

Understanding Maya’s naming convention is key to feeling comfortable and eventually predicting variable names when exploring further feature sets of the Maya API.

Nearly all Maya prefixes begin with the letter M; which of course stands for Maya and defines a Maya wrapper class. Next we have MFn; which stands for Maya Function set. For example MFnMesh, contains specific functions and variables that appropriately define a mesh (a mesh is a collection of vertices, normals and uv coordinates in 3D space) object in Maya. The MFn prefix is not limited to only visible objects in Maya. For instance, MFnDependencyNode is a conceptual object that is used to define a node inside the Maya graph architecture (we’ll cover the Maya architecture shortly, so don’t stress it).

Another important prefix in Maya is the MIt prefix that stands for Maya iterator. An iterator is not a difficult concept for those who are familiar with the STL library. It points towards some position in a data set (in this case a tree) and allows us for easy traversal, going to the next object ( itr.next() ) and looping until done ( while(!itr.isDone()) ).

The last and final prefix to take note of is the MPx. It stands for Maya Proxy object (see proxy). Quite simply it provides us with an interface towards integrating into Maya itself. Common uses of MPx are the MPxFileTranslator which we will be focusing on in this tutorial and the MPxCommand which allows the user to create his or her own custom Maya commands. For more information please reference the Maya Documentation.

Now that we are past the formalities, we can begin to talk about how Maya organizes it’s data, so that we can begin to extract from it. Essentially everything in Maya is stored inside a Directed Acyclic Graph or DAG (this one keyword will be very important so please take note of it now). For those familiar with web design this is equivalent to the HTML DOM object, for those not familiar I will refer to the data structure of a graph. The major difference in definition of a graph data structure and the DAG is that child nodes cannot be their own parents. See picture below.

Step 1 – creating a proxy

Create a new class and derive from MPxFileTranslator.

class CFileTranslator : public MPxFileTranslator

You will need to overload the following functions

static void * creator(void);

MStatus writer(const MFileObject& file, const MString& optionString, FileAccessMode mode);

bool haveWriteMethod(void)const { return true; }

MString defaultExtension() const { return “xml”;}

MString filter() const { return “*.xml”;}

Step 2 – creating a an exporter class

Our Maya exporter will execute after pushing file -> export all or file -> export selection. Our entry point is than inside the writer() function that we have overloaded. In order to check for selection we can perform the simple if check for mode == kExportActiveAccessMode else we export all. Since this is more of a feature than base functionality I won’t cover exporting by selection in any great detail but its implementation is not very different from exporting all.

We now have the simple design decision to write all our code inside the CFileTranslator class we created earlier or simply create a new class that will be specific towards our needs. We will want this new class to contain a few basic functions. Such as ClearAndReset(), ExportVertexData() and WriteToFile(). We will call these in that sequence from within the CFileTranslator’s writer() function.

Step 3 – data structures and data members

Next we’ll create some basic data structures that we’ll fill out during exporting. One thing to note is that we’ll be using Maya’s intrinsic data types such as MFloatPoint which is essentially Maya’s version of a 3-tulupe vector that contains floats for the x, y, and z coordinates.

typedef struct _tVertex

{

MFloatPoint point;

MFloatVector normal;

float uv[2];

}UniqueVertex;

Here we created a new datatype that will contain the vertex position (point), the vertex normal (normal) and the UV texture coordinates (uv[2]). As we export our data we’re looking to optimize Maya’s vertex list by creating avoid duplicate vertices and creating a unique vertex list. We’ll than create our own triangle list that store indices into this our array of unique vertices. For a better idea on how index buffers work, reference Chad Vernon’s website at (http://www.chadvernon.com/blog/tutorials/directx9/vertex-and-index-buffers/). So the last important data structure we’ll need to generate is our triangle.

typedef struct _tTriangle

{

unsigned int verts[3];

}Triangle;

std::vector<UniqueVertex>    m_UniqueVertList;

std::vector<Triangle>    m_TriangleList;

Wrapping the above into a mesh structure would allow us to export more than one mesh at a time. These are further improvements that you may consider making to the base exporter.

Step 4 – the loop

The idea is quite simple, but the work may become a little tedious. Our goal is to go through go through Maya’s DAG , find all the Meshes and export them. The tedious part is that we’ll be doing a very similar traversal for just about each part of the export process since the DAG contains everything from Mesh objects to lights and transforms.

Thankfully the iteration process is quite straightforward. We begin by creating a MItDag. We specify that we’ll be traversing in depth first order, and we’ll be looking for Meshes. The code should look something like this.

MItDag dagIt(MItDag::kDepthFirst, MFn::kMesh);

Next we loop through each element, each time checking if the Mesh is an intermediate object, which simply means it’s something left over in Maya history but is not the current model we continue. Else we begin exporting by calling GetMesh(), our own function that will fill out our data structures from earlier.

for (;!dagIt.isDone(); dagIt.next())

{

MDagPath currPath;

dagIt.getPath(currPath);

MFnMesh currMesh(currPath);

if (currMesh.isIntermediateObject())

continue;

GetMesh(currMesh);

}

Step 5 – Creating a unique vertex list from Maya’s data

We’re now inside the GetMesh() function at which point our prime objective is to fill out our m_UniqueVertList and m_TriangleList for our mesh. This is also a good time to go ahead and pull out things like the mesh transform, or any custom attributes if you so wish. Again we will not focus on these features and move onto the actual data.

We begin by creating a MDagPath object which essentially will contain the directory, or path if you will, of the mesh we are attempting to export.

MDagPath path;

currMesh.getPath(path);

Next we’ll create a new itterator to traverse the polygons of our mesh (aka triangles). We’ll also create a few arrays that we’ll populate with Maya’s vertex positions, vertex normals, and UV coordinates.

MItMeshPolygon polyItr(path);

MFloatPointArray _tPoints;

currMesh.getPoints(_tPoints);

MFloatVectorArray _tNormals;

currMesh.getNormals(_tNormals);

MFloatArray _tVArrays;

MFloatArray _tUArrays;

currMesh.getUVs(_tVArrays,_tUArrays);

Something to take note of now, is that the index of the vertex positions, normals, and UVs will all be unique. Although the index of the U and V coordinates is a 1:1, and will use the same value.

If you have kept up with this tutorial so far, congratulations, we’re now in the final stretch and I will simply go ahead and post up the code for generating the unique vertex list and triangle list per mesh. Remember that this code snippet is my own and your coding style may or may not adhere to it. The important part is that you understand the process involved.

for (; !polyItr.isDone(); polyItr.next())

{

Triangle tmpTriangle;

for (int vertIndex = 0; vertIndex < 3; ++vertIndex)

{

UniqueVertex tmpVertex;

tmpVertex.point = _tPoints[polyItr.vertexIndex(vertIndex)];

tmpVertex.normal = _tNormals[polyItr.normalIndex(vertIndex)];

int uvIndex = -1;

if(polyItr.getUVIndex(vertIndex, uvIndex))

{

tmpVertex.uv[0] = _tVArrays[uvIndex];

tmpVertex.uv[1] = _tUArrays[uvIndex];

}

else

continue; // this is a bad place to be!

bool exists = false;

int i = 0;

int size = m_UniqueVertList.size();

for (; i < size; ++i)

{

if(m_UniqueVertList[i].point == tmpVertex.point && m_UniqueVertList[i].normal == tmpVertex.normal &&

m_UniqueVertList[i].uv[0] == tmpVertex.uv[0] && m_UniqueVertList[i].uv[1] == tmpVertex.uv[1] )

{

exists = true;

break;

}

}

if (exists)

{

tmpTriangle.verts[vertIndex] = i;

continue;

}

tmpTriangle.verts[vertIndex] = m_UniqueVertList.size();

m_UniqueVertList.push_back(tmpVertex);

}

m_TriangleList.push_back(tmpTriangle);

}

Since I didn’t cover everything involved with creating a Maya exporter and assumed some familiarity, or rather ability to use the Maya Documentation, please feel free to post comments and ask questions. I’ll be glad to make clarifications, but at the moment I need to get back to work.

No Comments »



06
August
2008

Final Project Begins, It’s Go Time!

I’m excited, no thrilled, I’m so anxious I can’t find the words to describe how I feel right now. Its the first day of school again. Oh the antcipation. You know when you go to sleep right away, in hopes of making tomorrow come faster, only to wake up hours before thinking and dreaming about nothing else.

We finally made it to Final Project! The next five months will be the most important months for me at FullSail. They will define all that I’ve learned, they will define all that I’m capable of. These last months will be the last stepping stones towards breaking into my dream job. There’s nothing more to say but this.

No matter what happens, no matter what goes wrong, no matter what challanges lie ahead. Our final project will be amazing, I know it. And with the months to come, I think I’ll convince you!

No Comments »



03
August
2008

Inverse Kinematics and Jacobians

Robotic Arm

I recently wrote a paper on my research into procedural animation. We are only a few days from final project and my big game proposal is largely animation based. I thought it would be a good idea to put together a simple demonstration of Inverse Kinematics before Wednsday.

Although I was fairly successful at implementing the basic hierarchy, I am miles away from true IK. At the moment I’m attempting to comprehend Jacobians, but I feel my understanding for Calculus is really holding me back, as I’m having a hard time understanding fundemental concepts such as partial derivatives and how to represent derivites in code. Of course these are only set backs that I will resolve in the coming days.

For one I am glad I decided to keep this Unit Test very light and keep the process very itterative. This is usually quite the opposite to how I approach problems, but in this case it was largely to my benefit, as it allows for the implementation of small features before tackling the monster that is IK.

The steps I took are as follows:

  1. Render a joint on screen using D3DXCreateTeapot (later changed to D3DXCreateSphere)
  2. Add simple camera controls
  3. Build a simplified skeleton architectures. This involves joints, and bones.
    • A joint is packed with a 4×4 local and global matrix representing both orientation and translation.
    • A local matrix is relative to its parent or @ origin (identity matrix) if no parent is present.
    • A global matrix is set or computed by taking the inverse of the local matrix. (this step will refined later)
    • A joint contains a list of children (bones). This allows us to climb down the hierarchy.
    • A joint contains an index into it’s parent (joint). This allows us to climb up the hierarchy.
    • A bone contains an index into it’s fromJoint, and an index into it’s toJoint.
    • If a a bone contains no toJoint it is assumed as the endeffector.
  4. Build a DummySkeleton function that initializes a simple arm hierarchy as seen above. This is fast and easy, and would be later replaced with a filestream and a tool.
  5. Render the skeleton.
    • Rendering joints as sphere will allow for simple collision tests when regarding picking
    • Bones are rendered through D3DPT_LINELIST.
    • Utilization of recursive breadth first traversal and ID3DXMatrixStack for push, and pop functionality.
  6. Add picking (simply changing the appearance color of the joints for visual confirmation)
    • This will probably involve having to add additional information to an already rather large joint class.
  7. Add highlighed, and selected states to the joints.
    • Again I opted to keep these inside the joints
  8. When selected, translate the joint based on cursor position (should already be taken care of inside the picking algorithm). There is again some heavy use of inverses in this function, and this is where we can draw relationships between the data, to hopefully create better data structures during the next iteration.
  9. Although imo, a minor step before attempting true IK. Implementing bounds based on bone length and DOF values for the axis, we will be officially at the milestone of Dynamic Control.

No Comments »





Page 2 of 14123...Last »