Compare commits
7 Commits
db01667fb2
...
65dda0194d
Author | SHA1 | Date |
---|---|---|
Jarrod Doyle | 65dda0194d | |
Jarrod Doyle | 010757eb6f | |
Jarrod Doyle | bf47578133 | |
Jarrod Doyle | 0f9467b8c4 | |
Jarrod Doyle | a8bdf37097 | |
Jarrod Doyle | 9c71529d8e | |
Jarrod Doyle | e3aac88c17 |
|
@ -240,9 +240,11 @@ public class WorldRep : IChunk
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This ONLY works for rgba (bpp = 4)!!!
|
|
||||||
public void AddLight(int layer, int x, int y, float r, float g, float b)
|
public void AddLight(int layer, int x, int y, float r, float g, float b)
|
||||||
{
|
{
|
||||||
|
ArgumentOutOfRangeException.ThrowIfLessThan(layer, 0, nameof(layer));
|
||||||
|
ArgumentOutOfRangeException.ThrowIfGreaterThan(layer, Layers, nameof(layer));
|
||||||
|
|
||||||
var idx = (x + y * Width) * Bpp;
|
var idx = (x + y * Width) * Bpp;
|
||||||
var pLayer = Pixels[layer];
|
var pLayer = Pixels[layer];
|
||||||
switch (Bpp)
|
switch (Bpp)
|
||||||
|
|
|
@ -166,6 +166,7 @@ public class DbFile
|
||||||
"P$AnimLight" => new PropertyChunk<PropAnimLight>(),
|
"P$AnimLight" => new PropertyChunk<PropAnimLight>(),
|
||||||
"P$LightColo" => new PropertyChunk<PropLightColor>(),
|
"P$LightColo" => new PropertyChunk<PropLightColor>(),
|
||||||
"P$Spotlight" => new PropertyChunk<PropSpotlight>(),
|
"P$Spotlight" => new PropertyChunk<PropSpotlight>(),
|
||||||
|
"P$SpotAmb" => new PropertyChunk<PropSpotlightAndAmbient>(),
|
||||||
"P$RenderAlp" => new PropertyChunk<PropFloat>(),
|
"P$RenderAlp" => new PropertyChunk<PropFloat>(),
|
||||||
"LD$MetaProp" => new LinkDataMetaProp(),
|
"LD$MetaProp" => new LinkDataMetaProp(),
|
||||||
_ when entryName.StartsWith("L$") => new LinkChunk(),
|
_ when entryName.StartsWith("L$") => new LinkChunk(),
|
||||||
|
|
|
@ -103,6 +103,7 @@ public class ObjectHierarchy
|
||||||
AddProp<PropAnimLight>("P$AnimLight");
|
AddProp<PropAnimLight>("P$AnimLight");
|
||||||
AddProp<PropLightColor>("P$LightColo");
|
AddProp<PropLightColor>("P$LightColo");
|
||||||
AddProp<PropSpotlight>("P$Spotlight");
|
AddProp<PropSpotlight>("P$Spotlight");
|
||||||
|
AddProp<PropSpotlightAndAmbient>("P$SpotAmb");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Work out if there's some nice way to automatically decide if we inherit
|
// TODO: Work out if there's some nice way to automatically decide if we inherit
|
||||||
|
|
|
@ -288,6 +288,73 @@ public class ModelFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Apply transforms to normals and stuff
|
||||||
|
public void ApplyJoints(float[] joints)
|
||||||
|
{
|
||||||
|
// Build map of objects to their parent id
|
||||||
|
var objCount = Objects.Length;
|
||||||
|
var parentIds = new int[objCount];
|
||||||
|
for (var i = 0; i < objCount; i++)
|
||||||
|
{
|
||||||
|
parentIds[i] = -1;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < objCount; i++)
|
||||||
|
{
|
||||||
|
var subObj = Objects[i];
|
||||||
|
var childIdx = subObj.Child;
|
||||||
|
while (childIdx != -1)
|
||||||
|
{
|
||||||
|
parentIds[childIdx] = i;
|
||||||
|
childIdx = Objects[childIdx].Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate base transforms for every subobj (including joint)
|
||||||
|
var subObjTransforms = new Matrix4x4[objCount];
|
||||||
|
for (var i = 0; i < objCount; i++)
|
||||||
|
{
|
||||||
|
var subObj = Objects[i];
|
||||||
|
var objTrans = Matrix4x4.Identity;
|
||||||
|
if (subObj.Joint != -1)
|
||||||
|
{
|
||||||
|
var ang = float.DegreesToRadians(joints[subObj.Joint]);
|
||||||
|
// TODO: Is this correct? Should I use a manual rotation matrix?
|
||||||
|
var jointRot = Matrix4x4.CreateFromYawPitchRoll(0, ang, 0);
|
||||||
|
objTrans = jointRot * subObj.Transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
subObjTransforms[i] = objTrans;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sub object transforms
|
||||||
|
for (var i = 0; i < objCount; i++)
|
||||||
|
{
|
||||||
|
var subObj = Objects[i];
|
||||||
|
var transform = subObjTransforms[i];
|
||||||
|
|
||||||
|
// Build compound transformation
|
||||||
|
var parentId = parentIds[i];
|
||||||
|
while (parentId != -1)
|
||||||
|
{
|
||||||
|
transform *= subObjTransforms[parentId];
|
||||||
|
parentId = parentIds[parentId];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = 0; j < subObj.VhotCount; j++)
|
||||||
|
{
|
||||||
|
var v = VHots[subObj.VhotIdx + j];
|
||||||
|
v.Position = Vector3.Transform(v.Position, transform);
|
||||||
|
VHots[subObj.VhotIdx + j] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = 0; j < subObj.PointCount; j++)
|
||||||
|
{
|
||||||
|
var v = Vertices[subObj.PointIdx + j];
|
||||||
|
Vertices[subObj.PointIdx + j] = Vector3.Transform(v, transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryGetVhot(VhotId id, out VHot vhot)
|
public bool TryGetVhot(VhotId id, out VHot vhot)
|
||||||
{
|
{
|
||||||
foreach (var v in VHots)
|
foreach (var v in VHots)
|
||||||
|
|
|
@ -35,6 +35,30 @@ public class Light
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void FixRadius()
|
||||||
|
{
|
||||||
|
if (Radius == 0)
|
||||||
|
{
|
||||||
|
Radius = float.MaxValue;
|
||||||
|
R2 = float.MaxValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyTransforms(
|
||||||
|
Vector3 vhotLightPos,
|
||||||
|
Vector3 vhotLightDir,
|
||||||
|
Matrix4x4 translate,
|
||||||
|
Matrix4x4 rotate,
|
||||||
|
Matrix4x4 scale)
|
||||||
|
{
|
||||||
|
var transform = scale * rotate * translate;
|
||||||
|
vhotLightPos = Vector3.Transform(vhotLightPos, transform);
|
||||||
|
vhotLightDir = Vector3.Transform(vhotLightDir, transform);
|
||||||
|
|
||||||
|
Position = Vector3.Transform(Position, rotate) + vhotLightPos;
|
||||||
|
SpotlightDir = Vector3.Normalize(vhotLightDir - vhotLightPos);
|
||||||
|
}
|
||||||
|
|
||||||
public float StrengthAtPoint(Vector3 point, Plane plane)
|
public float StrengthAtPoint(Vector3 point, Plane plane)
|
||||||
{
|
{
|
||||||
// Calculate light strength at a given point. As far as I can tell
|
// Calculate light strength at a given point. As far as I can tell
|
||||||
|
|
|
@ -201,11 +201,13 @@ public class LightMapper
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var brightness = Math.Min(sz.X, 255.0f);
|
||||||
var light = new Light
|
var light = new Light
|
||||||
{
|
{
|
||||||
Position = brush.position,
|
Position = brush.position,
|
||||||
Color = Utils.HsbToRgb(sz.Y, sz.Z, Math.Min(sz.X, 255.0f)),
|
Color = Utils.HsbToRgb(sz.Y, sz.Z, brightness),
|
||||||
|
Brightness = brightness,
|
||||||
Radius = float.MaxValue,
|
Radius = float.MaxValue,
|
||||||
R2 = float.MaxValue,
|
R2 = float.MaxValue,
|
||||||
LightTableIndex = lightTable.LightCount,
|
LightTableIndex = lightTable.LightCount,
|
||||||
|
@ -219,108 +221,131 @@ public class LightMapper
|
||||||
{
|
{
|
||||||
// TODO: Handle PropSpotlightAndAmbient
|
// TODO: Handle PropSpotlightAndAmbient
|
||||||
var id = (int)brush.brushInfo;
|
var id = (int)brush.brushInfo;
|
||||||
|
var propScale = _hierarchy.GetProperty<PropVector>(id, "P$Scale");
|
||||||
var propAnimLight = _hierarchy.GetProperty<PropAnimLight>(id, "P$AnimLight", false);
|
var propAnimLight = _hierarchy.GetProperty<PropAnimLight>(id, "P$AnimLight", false);
|
||||||
var propLight = _hierarchy.GetProperty<PropLight>(id, "P$Light", false);
|
var propLight = _hierarchy.GetProperty<PropLight>(id, "P$Light", false);
|
||||||
var propLightColor = _hierarchy.GetProperty<PropLightColor>(id, "P$LightColo");
|
var propLightColor = _hierarchy.GetProperty<PropLightColor>(id, "P$LightColo");
|
||||||
var propSpotlight = _hierarchy.GetProperty<PropSpotlight>(id, "P$Spotlight");
|
var propSpotlight = _hierarchy.GetProperty<PropSpotlight>(id, "P$Spotlight");
|
||||||
|
var propSpotAmb = _hierarchy.GetProperty<PropSpotlightAndAmbient>(id, "P$SpotAmb");
|
||||||
var propModelName = _hierarchy.GetProperty<PropLabel>(id, "P$ModelName");
|
var propModelName = _hierarchy.GetProperty<PropLabel>(id, "P$ModelName");
|
||||||
|
var propJointPos = _hierarchy.GetProperty<PropJointPos>(id, "P$JointPos");
|
||||||
|
|
||||||
propLightColor ??= new PropLightColor { Hue = 0, Saturation = 0 };
|
propLightColor ??= new PropLightColor { Hue = 0, Saturation = 0 };
|
||||||
|
var joints = propJointPos?.Positions ?? [0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
// TODO: Also apply scale?
|
// Transform data
|
||||||
var rot = Matrix4x4.Identity;
|
var translate = Matrix4x4.CreateTranslation(brush.position);
|
||||||
rot *= Matrix4x4.CreateRotationX(float.DegreesToRadians(brush.angle.X));
|
var rotate = Matrix4x4.Identity;
|
||||||
rot *= Matrix4x4.CreateRotationY(float.DegreesToRadians(brush.angle.Y));
|
rotate *= Matrix4x4.CreateRotationX(float.DegreesToRadians(brush.angle.X));
|
||||||
rot *= Matrix4x4.CreateRotationZ(float.DegreesToRadians(brush.angle.Z));
|
rotate *= Matrix4x4.CreateRotationY(float.DegreesToRadians(brush.angle.Y));
|
||||||
|
rotate *= Matrix4x4.CreateRotationZ(float.DegreesToRadians(brush.angle.Z));
|
||||||
|
var scale = Matrix4x4.CreateScale(propScale?.value ?? Vector3.One);
|
||||||
|
|
||||||
var baseLight = new Light
|
var vhotLightPos = Vector3.Zero;
|
||||||
{
|
var vhotLightDir = -Vector3.UnitZ;
|
||||||
Position = brush.position,
|
|
||||||
SpotlightDir = Vector3.Transform(-Vector3.UnitZ, rot),
|
|
||||||
SpotlightInnerAngle = -1.0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (propModelName != null)
|
if (propModelName != null)
|
||||||
{
|
{
|
||||||
var resName = $"{propModelName.value.ToLower()}.bin";
|
var resName = $"{propModelName.value.ToLower()}.bin";
|
||||||
var modelPath = _campaign.GetResourcePath(ResourceType.Object, resName);
|
var modelPath = _campaign.GetResourcePath(ResourceType.Object, resName);
|
||||||
if (modelPath != null)
|
if (modelPath != null)
|
||||||
{
|
{
|
||||||
// TODO: Handle failing to find model more gracefully
|
|
||||||
var model = new ModelFile(modelPath);
|
var model = new ModelFile(modelPath);
|
||||||
|
model.ApplyJoints(joints);
|
||||||
|
|
||||||
if (model.TryGetVhot(ModelFile.VhotId.LightPosition, out var vhot))
|
if (model.TryGetVhot(ModelFile.VhotId.LightPosition, out var vhot))
|
||||||
{
|
{
|
||||||
baseLight.Position += Vector3.Transform(vhot.Position - model.Header.Center, rot);
|
vhotLightPos = vhot.Position - model.Header.Center;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (model.TryGetVhot(ModelFile.VhotId.LightDirection, out vhot))
|
if (model.TryGetVhot(ModelFile.VhotId.LightDirection, out vhot))
|
||||||
{
|
{
|
||||||
baseLight.SpotlightDir = Vector3.Transform(vhot.Position - model.Header.Center, rot);
|
vhotLightDir = vhot.Position - model.Header.Center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propSpotlight != null)
|
if (propAnimLight != null)
|
||||||
{
|
|
||||||
baseLight.Spotlight = true;
|
|
||||||
baseLight.SpotlightInnerAngle = (float)Math.Cos(float.DegreesToRadians(propSpotlight.InnerAngle));
|
|
||||||
baseLight.SpotlightOuterAngle = (float)Math.Cos(float.DegreesToRadians(propSpotlight.OuterAngle));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propLight != null && propLight.Brightness != 0f)
|
|
||||||
{
|
{
|
||||||
|
var lightIndex = lightTable.LightCount;
|
||||||
|
propAnimLight.LightTableLightIndex = (ushort)lightIndex;
|
||||||
|
|
||||||
var light = new Light
|
var light = new Light
|
||||||
{
|
{
|
||||||
Position = baseLight.Position + Vector3.Transform(propLight.Offset, rot),
|
Position = propAnimLight.Offset,
|
||||||
Color = Utils.HsbToRgb(propLightColor.Hue, propLightColor.Saturation, propLight.Brightness),
|
Color = Utils.HsbToRgb(propLightColor.Hue, propLightColor.Saturation, propAnimLight.MaxBrightness),
|
||||||
InnerRadius = propLight.InnerRadius,
|
Brightness = propAnimLight.Brightness,
|
||||||
Radius = propLight.Radius,
|
InnerRadius = propAnimLight.InnerRadius,
|
||||||
R2 = propLight.Radius * propLight.Radius,
|
Radius = propAnimLight.Radius,
|
||||||
QuadLit = propLight.QuadLit,
|
R2 = propAnimLight.Radius * propAnimLight.Radius,
|
||||||
Spotlight = baseLight.Spotlight,
|
QuadLit = propAnimLight.QuadLit,
|
||||||
SpotlightDir = baseLight.SpotlightDir,
|
ObjId = id,
|
||||||
SpotlightInnerAngle = baseLight.SpotlightInnerAngle,
|
LightTableIndex = propAnimLight.LightTableLightIndex,
|
||||||
SpotlightOuterAngle = baseLight.SpotlightOuterAngle,
|
Anim = true
|
||||||
LightTableIndex = lightTable.LightCount,
|
|
||||||
};
|
};
|
||||||
if (propLight.Radius == 0)
|
|
||||||
|
if (propSpotlight != null)
|
||||||
{
|
{
|
||||||
light.Radius = float.MaxValue;
|
light.Spotlight = true;
|
||||||
light.R2 = float.MaxValue;
|
light.SpotlightInnerAngle = (float)Math.Cos(float.DegreesToRadians(propSpotlight.InnerAngle));
|
||||||
|
light.SpotlightOuterAngle = (float)Math.Cos(float.DegreesToRadians(propSpotlight.OuterAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
light.FixRadius();
|
||||||
|
light.ApplyTransforms(vhotLightPos, vhotLightDir, translate, rotate, scale);
|
||||||
|
|
||||||
_lights.Add(light);
|
_lights.Add(light);
|
||||||
lightTable.AddLight(light.ToLightData(32.0f));
|
lightTable.AddLight(light.ToLightData(32.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propAnimLight != null)
|
if (propLight != null)
|
||||||
{
|
{
|
||||||
var lightIndex = lightTable.LightCount;
|
|
||||||
propAnimLight.LightTableLightIndex = (ushort)lightIndex;
|
|
||||||
|
|
||||||
var light = new Light
|
var light = new Light
|
||||||
{
|
{
|
||||||
Position = baseLight.Position + Vector3.Transform(propAnimLight.Offset, rot),
|
Position = propLight.Offset,
|
||||||
Color = Utils.HsbToRgb(propLightColor.Hue, propLightColor.Saturation, propAnimLight.MaxBrightness),
|
Color = Utils.HsbToRgb(propLightColor.Hue, propLightColor.Saturation, propLight.Brightness),
|
||||||
InnerRadius = propAnimLight.InnerRadius,
|
Brightness = propLight.Brightness,
|
||||||
Radius = propAnimLight.Radius,
|
InnerRadius = propLight.InnerRadius,
|
||||||
R2 = propAnimLight.Radius * propAnimLight.Radius,
|
Radius = propLight.Radius,
|
||||||
QuadLit = propAnimLight.QuadLit,
|
R2 = propLight.Radius * propLight.Radius,
|
||||||
Spotlight = baseLight.Spotlight,
|
QuadLit = propLight.QuadLit,
|
||||||
SpotlightDir = baseLight.SpotlightDir,
|
|
||||||
SpotlightInnerAngle = baseLight.SpotlightInnerAngle,
|
|
||||||
SpotlightOuterAngle = baseLight.SpotlightOuterAngle,
|
|
||||||
Anim = true,
|
|
||||||
ObjId = id,
|
ObjId = id,
|
||||||
LightTableIndex = propAnimLight.LightTableLightIndex,
|
LightTableIndex = lightTable.LightCount,
|
||||||
};
|
};
|
||||||
if (propAnimLight.Radius == 0)
|
|
||||||
|
if (propSpotAmb != null)
|
||||||
{
|
{
|
||||||
light.Radius = float.MaxValue;
|
var spot = new Light
|
||||||
light.R2 = float.MaxValue;
|
{
|
||||||
}
|
Position = light.Position,
|
||||||
|
Color = Utils.HsbToRgb(propLightColor.Hue, propLightColor.Saturation, propSpotAmb.SpotBrightness),
|
||||||
|
InnerRadius = light.InnerRadius,
|
||||||
|
Radius = light.Radius,
|
||||||
|
R2 = light.R2,
|
||||||
|
QuadLit = light.QuadLit,
|
||||||
|
Spotlight = true,
|
||||||
|
SpotlightInnerAngle = (float)Math.Cos(float.DegreesToRadians(propSpotAmb.InnerAngle)),
|
||||||
|
SpotlightOuterAngle = (float)Math.Cos(float.DegreesToRadians(propSpotAmb.OuterAngle)),
|
||||||
|
ObjId = light.ObjId,
|
||||||
|
LightTableIndex = light.LightTableIndex,
|
||||||
|
};
|
||||||
|
|
||||||
|
light.LightTableIndex++; // Because we're inserting the spotlight part first
|
||||||
|
|
||||||
|
spot.FixRadius();
|
||||||
|
spot.ApplyTransforms(vhotLightPos, vhotLightDir, translate, rotate, scale);
|
||||||
|
|
||||||
|
_lights.Add(spot);
|
||||||
|
lightTable.AddLight(spot.ToLightData(32.0f));
|
||||||
|
}
|
||||||
|
else if (propSpotlight != null)
|
||||||
|
{
|
||||||
|
light.Spotlight = true;
|
||||||
|
light.SpotlightInnerAngle = (float)Math.Cos(float.DegreesToRadians(propSpotlight.InnerAngle));
|
||||||
|
light.SpotlightOuterAngle = (float)Math.Cos(float.DegreesToRadians(propSpotlight.OuterAngle));
|
||||||
|
}
|
||||||
|
|
||||||
|
light.FixRadius();
|
||||||
|
light.ApplyTransforms(vhotLightPos, vhotLightDir, translate, rotate, scale);
|
||||||
|
|
||||||
_lights.Add(light);
|
_lights.Add(light);
|
||||||
lightTable.AddLight(light.ToLightData(32.0f));
|
lightTable.AddLight(light.ToLightData(32.0f));
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,7 @@ public class MeshBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's try and place an object :)
|
// Let's try and place an object :)
|
||||||
|
// TODO: Handle failing to find model more gracefully
|
||||||
var modelName = modelNameProp.value.ToLower() + ".bin";
|
var modelName = modelNameProp.value.ToLower() + ".bin";
|
||||||
var modelPath = campaignResources.GetResourcePath(ResourceType.Object, modelName);
|
var modelPath = campaignResources.GetResourcePath(ResourceType.Object, modelName);
|
||||||
if (modelPath == null)
|
if (modelPath == null)
|
||||||
|
@ -120,80 +121,15 @@ public class MeshBuilder
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle failing to find model more gracefully
|
|
||||||
var pos = brush.position;
|
|
||||||
var rot = brush.angle;
|
|
||||||
var scale = scaleProp?.value ?? Vector3.One;
|
|
||||||
var model = new ModelFile(modelPath);
|
var model = new ModelFile(modelPath);
|
||||||
pos -= model.Header.Center;
|
model.ApplyJoints(joints);
|
||||||
|
|
||||||
// Calculate base model transform
|
// Calculate base model transform
|
||||||
var scalePart = Matrix4x4.CreateScale(scale);
|
var transform = Matrix4x4.CreateScale(scaleProp?.value ?? Vector3.One);
|
||||||
var rotPart = Matrix4x4.Identity;
|
transform *= Matrix4x4.CreateRotationX(float.DegreesToRadians(brush.angle.X));
|
||||||
rotPart *= Matrix4x4.CreateRotationX(float.DegreesToRadians(rot.X));
|
transform *= Matrix4x4.CreateRotationY(float.DegreesToRadians(brush.angle.Y));
|
||||||
rotPart *= Matrix4x4.CreateRotationY(float.DegreesToRadians(rot.Y));
|
transform *= Matrix4x4.CreateRotationZ(float.DegreesToRadians(brush.angle.Z));
|
||||||
rotPart *= Matrix4x4.CreateRotationZ(float.DegreesToRadians(rot.Z));
|
transform *= Matrix4x4.CreateTranslation(brush.position - model.Header.Center);
|
||||||
var transPart = Matrix4x4.CreateTranslation(pos);
|
|
||||||
var modelTrans = scalePart * rotPart * transPart;
|
|
||||||
|
|
||||||
// Calculate base transforms for every subobj (including joint)
|
|
||||||
var objCount = model.Objects.Length;
|
|
||||||
var subObjTransforms = new Matrix4x4[objCount];
|
|
||||||
for (var i = 0; i < objCount; i++)
|
|
||||||
{
|
|
||||||
var subObj = model.Objects[i];
|
|
||||||
var objTrans = Matrix4x4.Identity;
|
|
||||||
if (subObj.Joint != -1)
|
|
||||||
{
|
|
||||||
var ang = float.DegreesToRadians(joints[subObj.Joint]);
|
|
||||||
// TODO: Is this correct? Should I use a manual rotation matrix?
|
|
||||||
var jointRot = Matrix4x4.CreateFromYawPitchRoll(0, ang, 0);
|
|
||||||
objTrans = jointRot * subObj.Transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
subObjTransforms[i] = objTrans;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build map of objects to their parent id
|
|
||||||
var parentIds = new int[objCount];
|
|
||||||
for (var i = 0; i < objCount; i++)
|
|
||||||
{
|
|
||||||
parentIds[i] = -1;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < objCount; i++)
|
|
||||||
{
|
|
||||||
var subObj = model.Objects[i];
|
|
||||||
var childIdx = subObj.Child;
|
|
||||||
while (childIdx != -1)
|
|
||||||
{
|
|
||||||
parentIds[childIdx] = i;
|
|
||||||
childIdx = model.Objects[childIdx].Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply sub object transforms + the base object transform to each vertex
|
|
||||||
for (var i = 0; i < objCount; i++)
|
|
||||||
{
|
|
||||||
var subObj = model.Objects[i];
|
|
||||||
var transform = subObjTransforms[i];
|
|
||||||
|
|
||||||
var parentId = parentIds[i];
|
|
||||||
while (parentId != -1)
|
|
||||||
{
|
|
||||||
transform *= subObjTransforms[parentId];
|
|
||||||
parentId = parentIds[parentId];
|
|
||||||
}
|
|
||||||
|
|
||||||
transform *= modelTrans;
|
|
||||||
|
|
||||||
var start = subObj.PointIdx;
|
|
||||||
var end = start + subObj.PointCount;
|
|
||||||
for (var j = start; j < end; j++)
|
|
||||||
{
|
|
||||||
var v = model.Vertices[j];
|
|
||||||
model.Vertices[j] = Vector3.Transform(v, transform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for each polygon slam its vertices and indices :)
|
// for each polygon slam its vertices and indices :)
|
||||||
foreach (var poly in model.Polygons)
|
foreach (var poly in model.Polygons)
|
||||||
|
@ -202,7 +138,9 @@ public class MeshBuilder
|
||||||
polyVertices.EnsureCapacity(poly.VertexCount);
|
polyVertices.EnsureCapacity(poly.VertexCount);
|
||||||
foreach (var idx in poly.VertexIndices)
|
foreach (var idx in poly.VertexIndices)
|
||||||
{
|
{
|
||||||
polyVertices.Add(model.Vertices[idx]);
|
var vertex = model.Vertices[idx];
|
||||||
|
vertex = Vector3.Transform(vertex, transform);
|
||||||
|
polyVertices.Add(vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddPolygon(polyVertices, SurfaceType.Solid);
|
AddPolygon(polyVertices, SurfaceType.Solid);
|
||||||
|
|
Loading…
Reference in New Issue