Author Topic: About camera in field file.  (Read 6406 times)

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
About camera in field file.
« on: 2006-06-21 04:17:59 »
Could someone post source of programm that load camera matrix. I get confused with it.

Cyberman

  • No life
  • *
  • Posts: 1571
  • Karma: 8
    • View Profile
Re: About camera in field file.
« Reply #1 on: 2006-06-21 05:11:51 »
Could someone post source of programm that load camera matrix. I get confused with it.
I believe this was discused when the walk map was being worked on in technical no?
Camera and walkmesh via Reunion
It doesn't seem to be there anymore (sigh) there was a huge long thing on the walk mesh information.  Someone had a nice viewer for it (unless that was you Akari :D)

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
Re: About camera in field file.
« Reply #2 on: 2006-06-21 16:59:17 »
Could someone post source of programm that load camera matrix. I get confused with it.
I believe this was discused when the walk map was being worked on in technical no?
Camera and walkmesh via Reunion
It doesn't seem to be there anymore (sigh) there was a huge long thing on the walk mesh information.  Someone had a nice viewer for it (unless that was you Akari :D)

I found description of sector 2 in this post http://forums.qhimm.com/index.php?topic=3247.0 as well as Kero programm that loads it. I has problems with signs of vectors... and maybe with something else. Just looking at code that loads this thing makes things much more clear.

sfx1999

  • No life
  • *
  • Posts: 1143
  • Karma: 0
    • View Profile
Re: About camera in field file.
« Reply #3 on: 2006-06-21 21:01:11 »
http://www.mevis.de/opengl/glLoadMatrix.html

You would use glLoadMatrixf.

Or are floats stored differently in FF7? If they are, I might be able to help with that.

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #4 on: 2006-06-21 23:02:12 »
Hiya,

If you're not averse to using glu then a simple gluLookAt is much easier. I've some code here if it helps but it's mostly the same as Kero's. For camera setup I've used the same internal structure except for floats for camera axes & instantiated an object from it:

Code: [Select]
cFieldCam.vy.x = -cFieldCam.vy.x;
cFieldCam.vy.y = -cFieldCam.vy.y;
cFieldCam.vy.z = -cFieldCam.vy.z;
cFieldCam.oy = -cFieldCam.oy;

cFieldCam.vx.x /= 4096.0f; cFieldCam.vx.y /= 4096.0f; cFieldCam.vx.z /= 4096.0f;
cFieldCam.vy.x /= 4096.0f; cFieldCam.vy.y /= 4096.0f; cFieldCam.vy.z /= 4096.0f;
cFieldCam.vz.x /= 4096.0f; cFieldCam.vz.y /= 4096.0f; cFieldCam.vz.z /= 4096.0f;

tx = -(cFieldCam.ox*cFieldCam.vx.x + cFieldCam.oy*cFieldCam.vy.x + cFieldCam.oz*cFieldCam.vz.x);
ty = -(cFieldCam.ox*cFieldCam.vx.y + cFieldCam.oy*cFieldCam.vy.y + cFieldCam.oz*cFieldCam.vz.y);
tz = -(cFieldCam.ox*cFieldCam.vx.z + cFieldCam.oy*cFieldCam.vy.z + cFieldCam.oz*cFieldCam.vz.z);

You can compact those lines if you want, this just makes it a bit clearer. Then the display code is simply:

Code: [Select]
glScalef(-1.0, 1.0, 1.0);
gluLookAt(tx, tz, ty, cFieldCam.vz.x, cFieldCam.vz.y, cFieldCam.vz.z, 0.0, 1.0, 0.0);

As you can see the z and y are flipped as per walkmesh vertices. I also find I have to scale the x-axis to flip the mesh as a whole, otherwise it renders the wrong way round but YMMV I guess as it could be something I've done wrong elsewhere.

Hope it helps.
« Last Edit: 2006-06-21 23:03:49 by Synergy Blades »

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
Re: About camera in field file.
« Reply #5 on: 2006-06-22 02:49:09 »
Synergy Blades, could you post struct and code that reads values from file (the walkmesh and camera). My error might be in there.

Here s mine

Code: [Select]
void
DatFile::GetWalkMesh(TotalGeometry &walkmesh)
{
    u32 offset_to_walkmesh = 0x1C + GetU32LE(0x04) - GetU32LE(0x00);

    Geometry geometry;
    geometry.TexEnabled = false;

    u32 number_of_poly = GetU32LE(offset_to_walkmesh);
    int start = offset_to_walkmesh + 0x04;

    for (u32 i = 0; i < number_of_poly; ++i)
    {
        Vertex v[3];

        v[0].p.x = -static_cast<s16>(GetU16LE(start + 0x00));
        v[0].p.z =  static_cast<s16>(GetU16LE(start + 0x02));
        v[0].p.y =  static_cast<s16>(GetU16LE(start + 0x04));
        v[0].c.r = 1.0f; v[0].c.g = 0.0f; v[0].c.b = 0.0f; v[0].c.a = 1.0f;
        v[1].p.x = -static_cast<s16>(GetU16LE(start + 0x08));
        v[1].p.z =  static_cast<s16>(GetU16LE(start + 0x0A));
        v[1].p.y =  static_cast<s16>(GetU16LE(start + 0x0C));
        v[1].c.r = 1.0f; v[1].c.g = 0.0f; v[1].c.b = 0.0f; v[1].c.a = 1.0f;
        v[2].p.x = -static_cast<s16>(GetU16LE(start + 0x10));
        v[2].p.z =  static_cast<s16>(GetU16LE(start + 0x12));
        v[2].p.y =  static_cast<s16>(GetU16LE(start + 0x14));
        v[2].c.r = 1.0f; v[2].c.g = 0.0f; v[2].c.b = 0.0f; v[2].c.a = 1.0f;

        geometry.AddTriangle(v);

        // go to the next triangle
        start += 0x18;

    }

    walkmesh.GeometryVector.push_back(geometry);
}

Code: [Select]
void
DatFile::GetCameraMatrix(Matrix &camera)
{
    u32 offset_to_camera = 0x1C + GetU32LE(0x0C) - GetU32LE(0x00);

    // get camera matrix (3 vectors)
    float vxx = static_cast<float>( static_cast<s16>(GetU16LE(offset_to_camera + 0x00))) / 4096.0f;
    float vxy = static_cast<float>( static_cast<s16>(GetU16LE(offset_to_camera + 0x04))) / 4096.0f;
    float vxz = static_cast<float>( static_cast<s16>(GetU16LE(offset_to_camera + 0x02))) / 4096.0f;

    float vyx = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x06))) / 4096.0f;
    float vyy = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x0A))) / 4096.0f;
    float vyz = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x08))) / 4096.0f;

    float vzx = static_cast<float>( static_cast<s16>(GetU16LE(offset_to_camera + 0x0C))) / 4096.0f;
    float vzy = static_cast<float>( static_cast<s16>(GetU16LE(offset_to_camera + 0x10))) / 4096.0f;
    float vzz = static_cast<float>( static_cast<s16>(GetU16LE(offset_to_camera + 0x0E))) / 4096.0f;

    Matrix mat(vxx, vyx, vzx, 0,
               vxy, vyy, vzy, 0,
               vxz, vyz, vzz, 0,
               0,   0,   0,   1);

    // get camera position in world
    s16 ox  =  static_cast<s16>(GetU16LE(offset_to_camera + 0x14));
    s16 oy  = -static_cast<s16>(GetU16LE(offset_to_camera + 0x16));
    s16 oz  =  static_cast<s16>(GetU16LE(offset_to_camera + 0x18));

    float tx = -(ox * vxx + oy * vyx + oz * vzx);
    float ty = -(ox * vxy + oy * vyy + oz * vzy);
    float tz = -(ox * vxz + oy * vyz + oz * vzz);

//    Matrix mat2;
//    MatrixTranslation(mat2, -tx, -ty, -tz);

//    printf("%f %f %f", tx, ty, tz);
//    MatrixMultiply(camera, mat, mat2);

    camera = LookAt(tx, ty, tz, vzx, vzy, vzz, 0, 1, 0);
}

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #6 on: 2006-06-22 11:20:36 »
Sure. The only thing I can spot just browsing your code seems to be your camera space coords are using S16s, not S32s.

Code: [Select]
template <class type>
struct WalkVertex
{
type x, z, y, r;
};

template <class type>
struct Camera
{
Vertex<type>  vx, vy, vz;
S16 repeat;
S32 ox, oy, oz;
S32 blank;
S16 size;
};

...

struct FF_CAMERA
{
U32 nSectionLength;
Camera<short> cCamera;

// Repeat data - this is not always here so read section length first to ascertain how much to read in!
S32 unknown1;
Camera<short> cRepeatCamera;
};

...

struct FF_WALKMESH
{
U32 nSectionLength;
U32 nSectors;
vector< WalkVertex<S16> > cVertexList;
vector<U16> cEdgeList;
};


I've templated the camera so can instantiate a float camera for the later calculations more easily.

File read:

Code: [Select]
// * SECTION TWO: Camera; get section length first as it varies
in.seekg(cMemory->sHeader.pSections[1], ifstream::beg);
in.read((char *)&cMemory->s2, sizeof(U32));

// - Now read in section based on section length, not struct size
in.seekg(cMemory->sHeader.pSections[1], ifstream::beg);
in.read((char *)&cMemory->s2, cMemory->s2.nSectionLength+4);

...

// * SECTION FIVE: Walkmesh
in.seekg(cMemory->sHeader.pSections[4], ifstream::beg);
in.read((char *)&cMemory->s5, 8);

// - Vertex list
WalkVertex<S16> cVert;
for(int i = 0; i < (int)cMemory->s5.nSectors * 3; i++)
{
in.read((char *)&cVert, sizeof(WalkVertex<S16>));
cMemory->s5.cVertexList.push_back(cVert);
}

// - Edges list
U16 cAccess;
for(int i = 0; i < (int)cMemory->s5.nSectors * 3; i++)
{
in.read((char *)&cAccess, sizeof(U16));
cMemory->s5.cEdgeList.push_back(cAccess);
}



The camera section length does actually vary, being one of two different lengths from file to file. For example, uutai1 has the 'section repeat' (length 0x4C) whereas church does not (length 0x26). Kero marked it down as not important but in testing I found that replacing the repeated data on uutai1 with blanks really messes it up - shrunken walkmesh and characters  (though I'm not sure if doing the same with the first set of data also messes the camera up, but I suspect not considering some fields don't need this extra data, but I will look into it further).
« Last Edit: 2006-06-22 13:16:53 by Synergy Blades »

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
Re: About camera in field file.
« Reply #7 on: 2006-06-22 18:29:50 »
It seems that "gluLookAt(tx, tz, ty, cFieldCam.vz.x, cFieldCam.vz.y, cFieldCam.vz.z, 0.0, 1.0, 0.0);" is wrong because " cFieldCam.vz.x, cFieldCam.vz.y, cFieldCam.vz.z" (where you looking at) is not coords but just ortonormal vector and it always near center of world matrix. But a lot of meshes are not placed in center of the world.

halkun

  • Global moderator
  • No life
  • *
  • Posts: 2111
  • Karma: 20
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: About camera in field file.
« Reply #8 on: 2006-06-22 19:25:44 »
Not to detract from the camera conversation. but it would be helpful to have some code to "overlay" the walkmesh over the background. This could be to detect alignment issues after most of the camera stuff is sorted out.

Keep in mind that some scenes have a "warped" projection. (The stairs in Shinra)


Here's an example of an "overlay" debug system from Sierra's AGI engine.
http://www.juhaterho.fi/agi/priority-explanation/

Keep in mind this is 2D, but helps track what's infront of who and where to do what.

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #9 on: 2006-06-22 19:56:45 »
Akari: isn't that sort of the point, that where the camera is pointing is down the z-axis - into the world? In which case the point where you want the camera to "look at" is anywhere along the z-axis? If the camera wasn't pointing at any point down the z-axis then surely the camera z-axis itself would be incorrect.

Halkun: fair point, this is the next thing I was looking at, but there's many factors that need to be taken into account; camera zoom (as Kero mentions, the camera covers the whole walkmesh, so it needs to be 'zoomed' to match the background), the Range in section 8 where the character can go off-center, and exactly where to place the image to align with the mesh. Also, what sort of warping are we talking about? I get the following walkmesh;



Interestingly the transition from stair-to-stair is not handled by a gateway in the usual fashion between fields on blinst_1 (there is no gateway where the top red arrow is, that's an added extra one) but rather, as far as I can tell, in the script for the field file; also the number of stairs on the mesh does not match the background image.
« Last Edit: 2006-06-22 20:11:23 by Synergy Blades »

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
Re: About camera in field file.
« Reply #10 on: 2006-06-22 20:16:23 »
Akari: isn't that sort of the point, that where the camera is pointing is down the z-axis - into the world? In which case the point where you want the camera to "look at" is anywhere along the z-axis? If the camera wasn't pointing at any point down the z-axis then surely the camera z-axis itself would be incorrect.

XYZ vectors are normalized vectors that sets camera position. Z vector set direction, but not the point in worldspace.

camera = LookAt(tx, ty, tz, tx + vzx, ty + vzy, tz + vzz, /*vyx, vyy, vyz*/ 0, 1, 0);

This is correct and works in most backgrounds... not in all of them though =(

Try lo load "data/FIELD/MD1STIN.DAT". This one is placed somewhere in 200, 200, 40000

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #11 on: 2006-06-22 20:24:50 »
Hmm.. good point. Infact even the orthographic view I'm using is way, way off for that one. I calculated it just using the min/max x/z values for the walkmesh and setting the glOrtho accordingly...



Works fine for all others :? Could it be a stray walkmesh value that causes the bounding box to be off? Really not sure, but that wouldn't explain the camera.
« Last Edit: 2006-06-22 20:40:05 by Synergy Blades »

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #12 on: 2006-06-22 20:39:09 »
Ah yes, now I remember from code long ago... field files with the same 'issue' that I have previously encountered:

ancnt2, ancnt3, ancnt4.

Though they are not as bad as in md1stin they are still 'off'. Might want to take a look at these in conjunction with md1stin and see if there's a common cause.

halkun

  • Global moderator
  • No life
  • *
  • Posts: 2111
  • Karma: 20
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: About camera in field file.
« Reply #13 on: 2006-06-22 21:22:27 »
l'm on PSP
Hard to type.
look at fieldscript. May contain SCR2* and other camera opcodes.
Sony! why no keyboard on PSP?

===EDIT===
Midgar station is correct ^_^
it is position before camera swoops down during opening movie.
(at instant colordepth drops and guards are overlaid on movie)
fieldscript starts @ movie beginning, not end.
work on debug rooms 1st.
eaiser, they are.
« Last Edit: 2006-06-22 21:39:15 by halkun »

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #14 on: 2006-06-22 21:42:56 »
Quote
l'm on PSP
Hard to type.
look at fieldscript. May contain SCR2* and other camera opcodes.
Sony! why no keyboard on PSP?

Best. Post. Ever.

Quote
it is position before camera swoops down during opening movie.

Ahah! Nice one, good thinking Batman. Debug rooms... fair enough, but their walkmeshes aren't that interesting  :-P By the way I've a script query - will PM you.

halkun

  • Global moderator
  • No life
  • *
  • Posts: 2111
  • Karma: 20
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: About camera in field file.
« Reply #15 on: 2006-06-22 21:54:19 »
Thanks, I'm on a "real Computer" for the moment.

The camera can be changed in the script itself. The probelm is I don't know where the camera paths are. The actual engine is desigened to allow movies to be skipped. (You execute a SPECIAL opcode, I think subfunction 0xFE) to disable movies. When engaged, Map 74 (Midgar Station) will jump to the inital action of the charcters jumping off the train and kicking the guards.

Covarr

  • Covarr-Let
  • Administrator
  • No life
  • *
  • Posts: 3913
  • Karma: 116
  • The Great Redarr.
    • View Profile
Re: About camera in field file.
« Reply #16 on: 2006-06-23 07:13:00 »
Do you have a DS? Opera DS is coming out in Japan this month, and the touchscreen makes a much better keyboard than buttons and a D-pad.

Quote
also the number of stairs on the mesh does not match the background image.
Is that the part of the game right before sector 7 collapses? It seems to me that since it switches to an entirely different field for the top, it doesn't matter as long as there's a warp to that field. Unless I'm misunderstanding your point, then ignore me... :)


Cyberman

  • No life
  • *
  • Posts: 1571
  • Karma: 8
    • View Profile
Re: About camera in field file.
« Reply #17 on: 2006-06-23 15:16:19 »
Do you have a DS? Opera DS is coming out in Japan this month, and the touchscreen makes a much better keyboard than buttons and a D-pad.

Quote
also the number of stairs on the mesh does not match the background image.
Is that the part of the game right before sector 7 collapses? It seems to me that since it switches to an entirely different field for the top, it doesn't matter as long as there's a warp to that field. Unless I'm misunderstanding your point, then ignore me... :)
Actually it's post Sector 7's demise because its from the Shinra building stair climb from heck.

Halkun, camera angles can be changed within the script? Dang! that might explain a few things.  Especially certain field areas where you move about the camera angle must change some.  Interesting.  For the Ps1 variant the script is already available (so to speak).  The field script must accept some input to skip a movie, I wonder if one can find the 'play movie' event and then find the end camera point from the opcode.

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
Re: About camera in field file.
« Reply #18 on: 2006-06-24 07:52:36 »
Yatta!!!1 Everything working. =)
Not trying to view second camera, but first is working everywhere.

ANCNT1


ANCNT4


CONDOR2


MD1STIN


MDS7


STARTMAP


Just as I say - camera = LookAt(tx, ty, tz, tx + vzx, ty + vzy, tz + vzz, vyx, vyy, vyz); - is true. Although I optimized this a little.

new camera reading
Code: [Select]
void
DatFile::GetCameraMatrix(Matrix &camera)
{
    u32 offset_to_camera = 0x1C + GetU32LE(0x0C) - GetU32LE(0x00);

    // get camera matrix (3 vectors)
    float vxx = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x00))) / 4096.0f;
    float vxy = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x04))) / 4096.0f;
    float vxz = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x02))) / 4096.0f;

    float vyx = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x06))) / 4096.0f;
    float vyy = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x0A))) / 4096.0f;
    float vyz = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x08))) / 4096.0f;

    float vzx = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x0C))) / 4096.0f;
    float vzy = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x10))) / 4096.0f;
    float vzz = static_cast<float>(-static_cast<s16>(GetU16LE(offset_to_camera + 0x0E))) / 4096.0f;

    // get camera position in world
    s32 ox  = -static_cast<s32>(GetU32LE(offset_to_camera + 0x14));
    s32 oy  = -static_cast<s32>(GetU32LE(offset_to_camera + 0x18));
    s32 oz  = -static_cast<s32>(GetU32LE(offset_to_camera + 0x1C));

    float tx = -(ox * vxx + oy * vyx + oz * vzx);
    float ty = -(ox * vxy + oy * vyy + oz * vzy);
    float tz = -(ox * vxz + oy * vyz + oz * vzz);

    Matrix mat(-vxx, vyx, vzx, 0,
               -vxy, vyy, vzy, 0,
               -vxz, vyz, vzz, 0,
               0,   0,   0,   1);

    Matrix mat2;
    MatrixTranslation(mat2, -tx, -ty, -tz);

    MatrixMultiply(camera, mat, mat2);
}

rmco2003

  • Guest
Re: About camera in field file.
« Reply #19 on: 2006-06-24 10:50:22 »
Looking good, is STARTMAP the debug room? It looks like it from the camera angle.

Synergy Blades

  • Guest
Re: About camera in field file.
« Reply #20 on: 2006-06-24 11:24:08 »
Cheers Akari, I tweaked my gluLookAt code and now md1stin works as expected  :-D

halkun

  • Global moderator
  • No life
  • *
  • Posts: 2111
  • Karma: 20
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: About camera in field file.
« Reply #21 on: 2006-06-24 19:04:33 »
STARTMAP is the first fieldfile executed from the engine. On load, it runs STARTMAP, then jumps to MD1STIN.

Now we need to overlay that over field backgound to see how well we line up. Remeber, FF7 field files run in a strange resolution. You may have to re-project with the top and bottom of the viewport "squished" to get the edges to line up.

On the subject of "The stairclimb from heck"

I'm playing FF7 again, this time keeping an eye out for odd things that the field files do. The perspective of the stairs look correct. I thought it was some kind of isometric projection. It looks good actually.


Cyberman

  • No life
  • *
  • Posts: 1571
  • Karma: 8
    • View Profile
Re: About camera in field file.
« Reply #22 on: 2006-06-24 20:20:52 »
So STARTMAP is loaded by the menu file that does the 'new game' etc?
When you select new game it then goes to STARTMAP?
Hmmm interesting very interesting.

Cyb

halkun

  • Global moderator
  • No life
  • *
  • Posts: 2111
  • Karma: 20
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: About camera in field file.
« Reply #23 on: 2006-06-24 20:24:46 »
My theory. I've seen the jumpmap to map 74 in STARTMAP. (74 == MD1STN). I'll have to look at the fieldscript....

Akari

  • Moderator
  • Freak
  • *
  • Posts: 759
  • Karma: 25
    • View Profile
Re: About camera in field file.
« Reply #24 on: 2006-06-24 21:28:13 »
My theory. I've seen the jumpmap to map 74 in STARTMAP. (74 == MD1STN). I'll have to look at the fieldscript....

74 is MD1STN
hmmm... where "filename" to "map id" assosiation stored?