Allow Cinematic Path nodes that only specify a camera position or direction and group them by deltatime.
Remove the support of saving the rotation of camera position nodes, because that should be rewritten to use a custom spline. Patch By: Vladislav Differential Revision: https://code.wildfiregames.com/D124 Refs #3814 This was SVN commit r19317.
This commit is contained in:
parent
76c7731076
commit
36330732fa
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -859,15 +859,16 @@ void CXMLReader::ReadPaths(XMBElement parent)
|
||||
CCinemaData pathData;
|
||||
XMBAttributeList attrs = element.GetAttributes();
|
||||
CStrW pathName(attrs.GetNamedItem(at_name).FromUTF8());
|
||||
pathData.m_Timescale = fixed::FromString(attrs.GetNamedItem(at_timescale));
|
||||
TNSpline pathSpline, targetSpline;
|
||||
fixed lastTargetTime = fixed::Zero();
|
||||
|
||||
pathData.m_Name = pathName;
|
||||
pathData.m_Timescale = fixed::FromString(attrs.GetNamedItem(at_timescale));
|
||||
pathData.m_Orientation = attrs.GetNamedItem(at_orientation).FromUTF8();
|
||||
pathData.m_Mode = attrs.GetNamedItem(at_mode).FromUTF8();
|
||||
pathData.m_Style = attrs.GetNamedItem(at_style).FromUTF8();
|
||||
|
||||
TNSpline positionSpline, targetSpline;
|
||||
fixed lastPositionTime = fixed::Zero();
|
||||
fixed lastTargetTime = fixed::Zero();
|
||||
|
||||
XERO_ITER_EL(element, pathChild)
|
||||
{
|
||||
elementName = pathChild.GetNodeName();
|
||||
@ -876,9 +877,7 @@ void CXMLReader::ReadPaths(XMBElement parent)
|
||||
// Load node data used for spline
|
||||
if (elementName == el_node)
|
||||
{
|
||||
bool positionDeclared = false;
|
||||
SplineData data;
|
||||
data.Distance = fixed::FromString(attrs.GetNamedItem(at_deltatime));
|
||||
lastPositionTime += fixed::FromString(attrs.GetNamedItem(at_deltatime));
|
||||
lastTargetTime += fixed::FromString(attrs.GetNamedItem(at_deltatime));
|
||||
XERO_ITER_EL(pathChild, nodeChild)
|
||||
{
|
||||
@ -887,16 +886,17 @@ void CXMLReader::ReadPaths(XMBElement parent)
|
||||
|
||||
if (elementName == el_position)
|
||||
{
|
||||
data.Position.X = fixed::FromString(attrs.GetNamedItem(at_x));
|
||||
data.Position.Y = fixed::FromString(attrs.GetNamedItem(at_y));
|
||||
data.Position.Z = fixed::FromString(attrs.GetNamedItem(at_z));
|
||||
positionDeclared = true;
|
||||
CFixedVector3D position;
|
||||
position.X = fixed::FromString(attrs.GetNamedItem(at_x));
|
||||
position.Y = fixed::FromString(attrs.GetNamedItem(at_y));
|
||||
position.Z = fixed::FromString(attrs.GetNamedItem(at_z));
|
||||
|
||||
positionSpline.AddNode(position, CFixedVector3D(), lastPositionTime);
|
||||
lastPositionTime = fixed::Zero();
|
||||
}
|
||||
else if (elementName == el_rotation)
|
||||
{
|
||||
data.Rotation.X = fixed::FromString(attrs.GetNamedItem(at_x));
|
||||
data.Rotation.Y = fixed::FromString(attrs.GetNamedItem(at_y));
|
||||
data.Rotation.Z = fixed::FromString(attrs.GetNamedItem(at_z));
|
||||
// TODO: Implement rotation slerp/spline as another object
|
||||
}
|
||||
else if (elementName == el_target)
|
||||
{
|
||||
@ -911,17 +911,13 @@ void CXMLReader::ReadPaths(XMBElement parent)
|
||||
else
|
||||
LOGWARNING("Invalid cinematic element for node child");
|
||||
}
|
||||
|
||||
// Skip the node if no position
|
||||
if (positionDeclared)
|
||||
pathSpline.AddNode(data.Position, data.Rotation, data.Distance);
|
||||
}
|
||||
else
|
||||
LOGWARNING("Invalid cinematic element for path child");
|
||||
}
|
||||
|
||||
// Construct cinema path with data gathered
|
||||
CCinemaPath path(pathData, pathSpline, targetSpline);
|
||||
CCinemaPath path(pathData, positionSpline, targetSpline);
|
||||
if (path.Empty())
|
||||
{
|
||||
LOGWARNING("Path with name '%s' is empty", pathName.ToUTF8());
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -409,7 +409,7 @@ void CMapWriter::WriteXML(const VfsPath& filename,
|
||||
for ( ; it != paths.end(); ++it )
|
||||
{
|
||||
fixed timescale = it->second.GetTimescale();
|
||||
const std::vector<SplineData>& nodes = it->second.GetAllNodes();
|
||||
const std::vector<SplineData>& position_nodes = it->second.GetAllNodes();
|
||||
const std::vector<SplineData>& target_nodes = it->second.GetTargetSpline().GetAllNodes();
|
||||
const CCinemaData* data = it->second.GetData();
|
||||
|
||||
@ -420,46 +420,55 @@ void CMapWriter::WriteXML(const VfsPath& filename,
|
||||
XML_Attribute("mode", data->m_Mode);
|
||||
XML_Attribute("style", data->m_Style);
|
||||
|
||||
struct SEvent
|
||||
{
|
||||
fixed time;
|
||||
const char* type;
|
||||
CFixedVector3D value;
|
||||
SEvent(fixed time, const char* type, CFixedVector3D value)
|
||||
: time(time), type(type), value(value)
|
||||
{}
|
||||
bool operator<(const SEvent& another)
|
||||
{
|
||||
return time < another.time;
|
||||
}
|
||||
};
|
||||
|
||||
// All events of a manipulating of camera (position/rotation/target)
|
||||
std::vector<SEvent> events;
|
||||
|
||||
fixed last_position = fixed::Zero();
|
||||
for (size_t i = 0; i < position_nodes.size(); ++i)
|
||||
{
|
||||
fixed distance = i > 0 ? position_nodes[i - 1].Distance : fixed::Zero();
|
||||
last_position += distance;
|
||||
events.emplace_back(last_position, "Position", position_nodes[i].Position);
|
||||
}
|
||||
|
||||
fixed last_target = fixed::Zero();
|
||||
for (size_t i = 0, j = 0; i < nodes.size(); ++i)
|
||||
for (size_t i = 0; i < target_nodes.size(); ++i)
|
||||
{
|
||||
fixed distance = i > 0 ? target_nodes[i - 1].Distance : fixed::Zero();
|
||||
last_target += distance;
|
||||
events.emplace_back(last_target, "Target", target_nodes[i].Position);
|
||||
}
|
||||
|
||||
std::sort(events.begin(), events.end());
|
||||
for (size_t i = 0; i < events.size();)
|
||||
{
|
||||
XML_Element("Node");
|
||||
fixed distance = i > 0 ? nodes[i - 1].Distance : fixed::Zero();
|
||||
last_target += distance;
|
||||
|
||||
XML_Attribute("deltatime", distance);
|
||||
|
||||
fixed deltatime = i > 0 ? (events[i].time - events[i - 1].time) : fixed::Zero();
|
||||
XML_Attribute("deltatime", deltatime);
|
||||
size_t j = i;
|
||||
for (; j < events.size() && events[j].time == events[i].time; ++j)
|
||||
{
|
||||
XML_Element("Position");
|
||||
XML_Attribute("x", nodes[i].Position.X);
|
||||
XML_Attribute("y", nodes[i].Position.Y);
|
||||
XML_Attribute("z", nodes[i].Position.Z);
|
||||
// Types: Position/Rotation/Target
|
||||
XML_Element(events[j].type);
|
||||
XML_Attribute("x", events[j].value.X);
|
||||
XML_Attribute("y", events[j].value.Y);
|
||||
XML_Attribute("z", events[j].value.Z);
|
||||
}
|
||||
|
||||
{
|
||||
XML_Element("Rotation");
|
||||
XML_Attribute("x", nodes[i].Rotation.X);
|
||||
XML_Attribute("y", nodes[i].Rotation.Y);
|
||||
XML_Attribute("z", nodes[i].Rotation.Z);
|
||||
}
|
||||
|
||||
if (j >= target_nodes.size())
|
||||
continue;
|
||||
|
||||
fixed target_distance = j > 0 ? target_nodes[j - 1].Distance : fixed::Zero();
|
||||
|
||||
if (target_distance > last_target)
|
||||
continue;
|
||||
|
||||
{
|
||||
XML_Element("Target");
|
||||
XML_Attribute("x", target_nodes[j].Position.X);
|
||||
XML_Attribute("y", target_nodes[j].Position.Y);
|
||||
XML_Attribute("z", target_nodes[j].Position.Z);
|
||||
}
|
||||
|
||||
last_target = fixed::Zero();
|
||||
++j;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user