Jump to content

SharpOcarina - Zelda OoT Scene Development System


xdaniel
 Share

Recommended Posts

1) SharpOcarina v0.2 released: http://magicstone.de...Ocarina-v02.rar (still binary only, as there's still too many bugs for my liking...)

- Bugfixes in model and material parser, texture loader and a few other places

- Backface culling can be disabled/enabled per group

- Minor changes in Display List generation

 

2) SanguinettiMods, just for the record - because that threw me off before as well -, you did try to import your map into a fresh, unpatched Debug ROM and did not load a savestate ex. to get to the map select faster? I had weird collision issues with one of the problem maps Arcaith posted once, because I used a savestate from a different Debug ROM to access map select. The map worked, but it froze when I went to certain places, and some collision polygons were defined as exits which froze the game because there was no exit table defined.

 

 

I tried a New, Clean, Debug ROM each time. And I never used a SaveState.

When I go to far, it freezes. That's it.

Link to comment
Share on other sites

I can't spot anything wrong with the algorithm; the normal vector is calculated correctly (I do find it odd that 0x8001 is -1.0 instead of 0x8000 but that's just me).

fffffffffuuuuuuu I keep reading stuff wrong so I'll go and test this again I should stop going to sleep at 3AM

 

 

Okay so everything in the algorithm is correct except this part:

 

...(nf[2] / 0x7FFF) * p1[2])

 

The yellow bracket should come just before the red one, so that it looks like:

...(nf[2] / 0x7FFF * p1[2]))

 

If it were me, I'd rewrite that line as:

dn = (int)( (nf[0] * p1[0] / 0x7FFF) + (nf[1] * p1[1] / 0x7FFF) + (nf[2] * p1[2] / 0x7FFF) ) * -1;

I think C# does multiplication first; if that's the case then the original line would have produced terrible results anyway because it was written to be executed in the order it appears (ex. nf[0]/0x7FFF, then result*p1[0]).

Link to comment
Share on other sites

Yeah, thanks for the fix. Just updated the code in SharpOcarina, although I don't have any test cases that produce broken collision handy. I'll release another build with that, plus some changes to the texture converter so that it uses CI-type and other more space saving texture types more often than before, as most textures originally ended up as RGBA 16-bit no matter what. Also will see about creating a new SVN for the project...

 

SVN created, source is now available: http://code.google.com/p/sharpocarina/

 

New build coming after I rebooted, updated TortoiseSVN which now wants me to do just that... is here: http://code.google.com/p/sharpocarina/downloads/detail?name=SharpOcarina-v03.rar

Link to comment
Share on other sites

Have you tried with no actors/objects present?

There shouldn't still be a problem with the collision since normals and distance are calculated correctly. If there is, it could be to do with using (int); I don't know if that rounds or truncates (I know nothing of C#) but you may need to try using math.round or math.ceiling. If there's still a problem then it could be anything but we'll probably find it eventually.

Link to comment
Share on other sites

dn = (int)( (nf[0] * p1[0] / 0x7FFF) + (nf[1] * p1[1] / 0x7FFF) + (nf[2] * p1[2] / 0x7FFF) ) * -1;

 

I just realized this could potentially lead to overflow (on 32-bit machines); it would be better written with the division in the middle

 

dn = (int)( (nf[0] / 0x7FFF * p1[0]) + (nf[1] / 0x7FFF * p1[1]) + (nf[2] / 0x7FFF * p1[2]) ) * -1;

Link to comment
Share on other sites

...

I just realized this could potentially lead to overflow (on 32-bit machines); it would be better written with the division in the middle

...

 

True, I'm just more used to writing stuff like this by hand where the order doesn't matter too much.

We would need to add some extra brackets so that it executes correctly though:

 

dn = (int)( ((nf[0] / 0x7FFF) * p1[0]) + ((nf[1] / 0x7FFF) * p1[1]) + ((nf[2] / 0x7FFF) * p1[2]) ) * -1;

 

This way we can avoid having C# see it as nf/(0x7FFF*p1).

 

I think I'll try rewriting the whole algorithm from scratch so I can pinpoint any errors that are still there.

Link to comment
Share on other sites

Small bug: changes to alpha values aren't working. Also, textures with per pixel alpha have black outlines. I'm not sure if this is a problem with the textures themselves, but it is present. Here's a comparison shot.

 

Posted Image

 

Black outlines should have been fixed, changed the render mode for textures with alpha channel. As for the other bug, you mean the per-group alpha for translucency? I don't have any problems with that, at least on the maps I tried (your castle one here, the demo dungeon). Is the alpha only ignored when importing, or is the preview already not showing the changes?

Link to comment
Share on other sites

When I tried it was ignored when importing. It was showing the changes in the model viewer, but when I imported there weren't there. I was trying with a water texture though, I could try with a fence too I guess.

 

I tried with a different texture and there was no problems with the alpha. Well, the alpha that's "built" into the texture. I can't get the alpha to change when using the function on Sharp Ocarina though.

Link to comment
Share on other sites

xdaniel, this is part of my collision fixing code (written in Delphi because I'm more familiar with it):

 

	//get two vectors in the plane, head to tail
	d[0].x := v[0].x - v[1].x;
	d[0].y := v[0].y - v[1].y;
	d[0].z := v[0].z - v[1].z;
	d[1].x := v[1].x - v[2].x;
	d[1].y := v[1].y - v[2].y;
	d[1].z := v[1].z - v[2].z;
	//use the cross product to find the normal vector
	normal.x:=(d[0].y * d[1].z) - (d[0].z * d[1].y);
	normal.y:=(d[0].z * d[1].x) - (d[0].x * d[1].z);
	normal.z:=(d[0].x * d[1].y) - (d[0].y * d[1].x);
	//find its length
	length:=sqr(normal.x) + sqr(normal.y) + sqr(normal.z);
	length:=sqrt(length);
	//now find the unit vector
	if length <> 0 then
	  begin
		unitnormal.x := normal.x / length;
		unitnormal.y := normal.y / length;
		unitnormal.z := normal.z / length;
	  end;
	//Zelda uses 0x7FFF as 1.0 so...
	normaldir.x := round(unitnormal.x * 32767);
	normaldir.y := round(unitnormal.y * 32767);
	normaldir.z := round(unitnormal.z * 32767);
	//now find the perpendicular distance from plane to origin
	distance := round(((v[0].x * unitnormal.x) + (v[0].y * unitnormal.y) + (v[0].z * unitnormal.z)) * -1);
	//we have everything calculated now, time to write it
I tested it with Hyrule Field's collision and its output was exactly the same as an unedited version, which is a good sign.

 

Source code and executable here if anybody wants it.

Usage:

collisionfix (scene file)

 

The problem with your code seems to be this:

		for (i = 0; i < 3; i++)
		{
			if (nd != 0)
				nf[i] /= nd;
			nf[i] *= 0x3FFF0001;
			nf[i] = (float)Math.Sqrt((double)nf[i]);
			if (ni[i] < 0)
				nf[i] *= -1;
		}
Which should just be:

		for (i = 0; i < 3; i++)
		{
			if (nd != 0)
				nf[i] /= nd;
			nf[i] *= 0x7FFF
		}
Or at least that's what my algorithm does differently. It may still be down to a rounding error somewhere else though so I'd advise you to check over the code a bit more.

 

Edit: more good news, I ran this with a map created with SM642Z64 and the map now seems to be crash-free.

Link to comment
Share on other sites

Ugh, I can't seem to get the collision normals right, even with DeathBasket's code... Just changing the existing code the way you described didn't work, with the resulting normals being even worse than before, and I'm apparently too stupid to correctly port the Delphi code to C#, because that also resulted in literal collision failure. As for the current code - using Zeth's old testing map I mentioned -, it appears to be mostly off-by-one rounding errors but there's also a few instances where there's only zeros being written, while your collisionfix writes actual values. Hell if I knew how I'm doing it wrong...

 

As for Kd commands in materials, I guess I'll see what I can do once the whole collision fiasco is sorted out...

 

And finally, as for alpha translucency, you cannot have that and a texture with an alpha channel together, at least with the way combiner and render modes are created currently.

Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.