many fixes
This commit is contained in:
@@ -504,6 +504,13 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
|
||||
}
|
||||
|
||||
if (state.materialArray.empty())
|
||||
{
|
||||
Entity materialEntity = scene.Entity_CreateMaterial("GLTFImport_defaultMaterial");
|
||||
model.materials.insert(materialEntity);
|
||||
state.materialArray.push_back(materialEntity);
|
||||
}
|
||||
|
||||
// Create meshes:
|
||||
for (auto& x : state.gltfModel.meshes)
|
||||
{
|
||||
@@ -525,44 +532,45 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
const tinygltf::Buffer& buffer = state.gltfModel.buffers[bufferView.buffer];
|
||||
|
||||
int stride = accessor.ByteStride(bufferView);
|
||||
size_t count = accessor.count;
|
||||
size_t offset = mesh.indices.size();
|
||||
mesh.indices.resize(offset + count);
|
||||
|
||||
assert(prim.material >= 0);
|
||||
size_t indexCount = accessor.count;
|
||||
size_t indexOffset = mesh.indices.size();
|
||||
mesh.indices.resize(indexOffset + indexCount);
|
||||
|
||||
mesh.subsets.push_back(MeshComponent::MeshSubset());
|
||||
mesh.subsets.back().materialID = state.materialArray[prim.material];
|
||||
mesh.subsets.back().indexOffset = (uint32_t)offset;
|
||||
mesh.subsets.back().indexCount = (uint32_t)count;
|
||||
mesh.subsets.back().indexOffset = (uint32_t)indexOffset;
|
||||
mesh.subsets.back().indexCount = (uint32_t)indexCount;
|
||||
|
||||
mesh.subsets.back().materialID = state.materialArray[max(0, prim.material)];
|
||||
|
||||
uint32_t vertexOffset = (uint32_t)mesh.vertex_positions.size();
|
||||
|
||||
const unsigned char* data = buffer.data.data() + accessor.byteOffset + bufferView.byteOffset;
|
||||
|
||||
if (stride == 1)
|
||||
{
|
||||
for (size_t i = 0; i < count; i += 3)
|
||||
for (size_t i = 0; i < indexCount; i += 3)
|
||||
{
|
||||
mesh.indices[offset + i + 0] = data[i + 0];
|
||||
mesh.indices[offset + i + 1] = data[i + 1];
|
||||
mesh.indices[offset + i + 2] = data[i + 2];
|
||||
mesh.indices[indexOffset + i + 0] = vertexOffset + data[i + 0];
|
||||
mesh.indices[indexOffset + i + 1] = vertexOffset + data[i + 1];
|
||||
mesh.indices[indexOffset + i + 2] = vertexOffset + data[i + 2];
|
||||
}
|
||||
}
|
||||
else if (stride == 2)
|
||||
{
|
||||
for (size_t i = 0; i < count; i += 3)
|
||||
for (size_t i = 0; i < indexCount; i += 3)
|
||||
{
|
||||
mesh.indices[offset + i + 0] = ((uint16_t*)data)[i + 0];
|
||||
mesh.indices[offset + i + 1] = ((uint16_t*)data)[i + 1];
|
||||
mesh.indices[offset + i + 2] = ((uint16_t*)data)[i + 2];
|
||||
mesh.indices[indexOffset + i + 0] = vertexOffset + ((uint16_t*)data)[i + 0];
|
||||
mesh.indices[indexOffset + i + 1] = vertexOffset + ((uint16_t*)data)[i + 1];
|
||||
mesh.indices[indexOffset + i + 2] = vertexOffset + ((uint16_t*)data)[i + 2];
|
||||
}
|
||||
}
|
||||
else if (stride == 4)
|
||||
{
|
||||
for (size_t i = 0; i < count; i += 3)
|
||||
for (size_t i = 0; i < indexCount; i += 3)
|
||||
{
|
||||
mesh.indices[offset + i + 0] = ((uint32_t*)data)[i + 0];
|
||||
mesh.indices[offset + i + 1] = ((uint32_t*)data)[i + 1];
|
||||
mesh.indices[offset + i + 2] = ((uint32_t*)data)[i + 2];
|
||||
mesh.indices[indexOffset + i + 0] = vertexOffset + ((uint32_t*)data)[i + 0];
|
||||
mesh.indices[indexOffset + i + 1] = vertexOffset + ((uint32_t*)data)[i + 1];
|
||||
mesh.indices[indexOffset + i + 2] = vertexOffset + ((uint32_t*)data)[i + 2];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -580,47 +588,43 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
const tinygltf::Buffer& buffer = state.gltfModel.buffers[bufferView.buffer];
|
||||
|
||||
int stride = accessor.ByteStride(bufferView);
|
||||
size_t count = accessor.count;
|
||||
size_t vertexCount = accessor.count;
|
||||
|
||||
const unsigned char* data = buffer.data.data() + accessor.byteOffset + bufferView.byteOffset;
|
||||
|
||||
if (!attr_name.compare("POSITION"))
|
||||
{
|
||||
size_t offset = mesh.vertex_positions.size();
|
||||
mesh.vertex_positions.resize(mesh.vertex_positions.size() + count);
|
||||
mesh.vertex_positions.resize(vertexOffset + vertexCount);
|
||||
assert(stride == 12);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
mesh.vertex_positions[offset + i] = ((XMFLOAT3*)data)[i];
|
||||
mesh.vertex_positions[vertexOffset + i] = ((XMFLOAT3*)data)[i];
|
||||
}
|
||||
}
|
||||
else if (!attr_name.compare("NORMAL"))
|
||||
{
|
||||
size_t offset = mesh.vertex_normals.size();
|
||||
mesh.vertex_normals.resize(mesh.vertex_normals.size() + count);
|
||||
mesh.vertex_normals.resize(vertexOffset + vertexCount);
|
||||
assert(stride == 12);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
mesh.vertex_normals[offset + i] = ((XMFLOAT3*)data)[i];
|
||||
mesh.vertex_normals[vertexOffset + i] = ((XMFLOAT3*)data)[i];
|
||||
}
|
||||
}
|
||||
else if (!attr_name.compare("TEXCOORD_0"))
|
||||
{
|
||||
size_t offset = mesh.vertex_texcoords.size();
|
||||
mesh.vertex_texcoords.resize(mesh.vertex_texcoords.size() + count);
|
||||
mesh.vertex_texcoords.resize(vertexOffset + vertexCount);
|
||||
assert(stride == 8);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
const XMFLOAT2& tex = ((XMFLOAT2*)data)[i];
|
||||
|
||||
mesh.vertex_texcoords[offset + i].x = tex.x;
|
||||
mesh.vertex_texcoords[offset + i].y = tex.y;
|
||||
mesh.vertex_texcoords[vertexOffset + i].x = tex.x;
|
||||
mesh.vertex_texcoords[vertexOffset + i].y = tex.y;
|
||||
}
|
||||
}
|
||||
else if (!attr_name.compare("JOINTS_0"))
|
||||
{
|
||||
size_t offset = mesh.vertex_boneindices.size();
|
||||
mesh.vertex_boneindices.resize(mesh.vertex_boneindices.size() + count);
|
||||
mesh.vertex_boneindices.resize(vertexOffset + vertexCount);
|
||||
if (stride == 4)
|
||||
{
|
||||
struct JointTmp
|
||||
@@ -628,14 +632,14 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
uint8_t ind[4];
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
const JointTmp& joint = ((JointTmp*)data)[i];
|
||||
|
||||
mesh.vertex_boneindices[offset + i].x = joint.ind[0];
|
||||
mesh.vertex_boneindices[offset + i].y = joint.ind[1];
|
||||
mesh.vertex_boneindices[offset + i].z = joint.ind[2];
|
||||
mesh.vertex_boneindices[offset + i].w = joint.ind[3];
|
||||
mesh.vertex_boneindices[vertexOffset + i].x = joint.ind[0];
|
||||
mesh.vertex_boneindices[vertexOffset + i].y = joint.ind[1];
|
||||
mesh.vertex_boneindices[vertexOffset + i].z = joint.ind[2];
|
||||
mesh.vertex_boneindices[vertexOffset + i].w = joint.ind[3];
|
||||
}
|
||||
}
|
||||
else if (stride == 8)
|
||||
@@ -645,14 +649,14 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
uint16_t ind[4];
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
const JointTmp& joint = ((JointTmp*)data)[i];
|
||||
|
||||
mesh.vertex_boneindices[offset + i].x = joint.ind[0];
|
||||
mesh.vertex_boneindices[offset + i].y = joint.ind[1];
|
||||
mesh.vertex_boneindices[offset + i].z = joint.ind[2];
|
||||
mesh.vertex_boneindices[offset + i].w = joint.ind[3];
|
||||
mesh.vertex_boneindices[vertexOffset + i].x = joint.ind[0];
|
||||
mesh.vertex_boneindices[vertexOffset + i].y = joint.ind[1];
|
||||
mesh.vertex_boneindices[vertexOffset + i].z = joint.ind[2];
|
||||
mesh.vertex_boneindices[vertexOffset + i].w = joint.ind[3];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -662,12 +666,11 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
}
|
||||
else if (!attr_name.compare("WEIGHTS_0"))
|
||||
{
|
||||
size_t offset = mesh.vertex_boneweights.size();
|
||||
mesh.vertex_boneweights.resize(mesh.vertex_boneweights.size() + count);
|
||||
mesh.vertex_boneweights.resize(vertexOffset + vertexCount);
|
||||
assert(stride == 16);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
mesh.vertex_boneweights[offset + i] = ((XMFLOAT4*)data)[i];
|
||||
mesh.vertex_boneweights[vertexOffset + i] = ((XMFLOAT4*)data)[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,7 +717,7 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
}
|
||||
|
||||
// Create transform hierarchy, assign objects, meshes, armatures, cameras:
|
||||
const tinygltf::Scene &gltfScene = state.gltfModel.scenes[state.gltfModel.defaultScene];
|
||||
const tinygltf::Scene &gltfScene = state.gltfModel.scenes[max(0, state.gltfModel.defaultScene)];
|
||||
for (size_t i = 0; i < gltfScene.nodes.size(); i++)
|
||||
{
|
||||
LoadNode(&state.gltfModel.nodes[gltfScene.nodes[i]], state.modelEntity, state);
|
||||
@@ -775,21 +778,12 @@ Entity ImportModel_GLTF(const std::string& fileName)
|
||||
|
||||
assert(stride == 4);
|
||||
|
||||
float start = FLT_MAX;
|
||||
float end = 0.0f;
|
||||
animationcomponent.length = 0.0f;
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
float time = ((float*)data)[i];
|
||||
animationcomponent.channels.back().keyframe_times[i] = time;
|
||||
start = min(start, time);
|
||||
end = max(end, time);
|
||||
}
|
||||
|
||||
// Cut empty animation from beginning:
|
||||
animationcomponent.length = end - start;
|
||||
for (auto& time : animationcomponent.channels.back().keyframe_times)
|
||||
{
|
||||
time -= start;
|
||||
animationcomponent.length = max(animationcomponent.length, time);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+43
-48
@@ -7843,10 +7843,6 @@ wiRenderer::RayIntersectWorldResult wiRenderer::RayIntersectWorld(const RAY& ray
|
||||
const XMVECTOR rayOrigin = XMLoadFloat3(&ray.origin);
|
||||
const XMVECTOR rayDirection = XMVector3Normalize(XMLoadFloat3(&ray.direction));
|
||||
|
||||
// pre allocate helper vector array:
|
||||
static size_t _arraySize = 10000;
|
||||
static XMVECTOR* _vertices = (XMVECTOR*)_mm_malloc(sizeof(XMVECTOR)*_arraySize, 16);
|
||||
|
||||
for (size_t i = 0; i < scene.objects.GetCount(); ++i)
|
||||
{
|
||||
Entity entity = scene.objects.GetEntity(i);
|
||||
@@ -7873,13 +7869,6 @@ wiRenderer::RayIntersectWorldResult wiRenderer::RayIntersectWorld(const RAY& ray
|
||||
}
|
||||
|
||||
const MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID);
|
||||
if (mesh.vertex_positions.size() >= _arraySize)
|
||||
{
|
||||
// grow preallocated vector helper array
|
||||
_mm_free(_vertices);
|
||||
_arraySize = (mesh.vertex_positions.size() + 1) * 2;
|
||||
_vertices = (XMVECTOR*)_mm_malloc(sizeof(XMVECTOR)*_arraySize, 16);
|
||||
}
|
||||
|
||||
const TransformComponent& transform = *scene.transforms.GetComponent(entity);
|
||||
|
||||
@@ -7889,41 +7878,6 @@ wiRenderer::RayIntersectWorldResult wiRenderer::RayIntersectWorld(const RAY& ray
|
||||
const XMVECTOR rayOrigin_local = XMVector3Transform(rayOrigin, objectMat_Inverse);
|
||||
const XMVECTOR rayDirection_local = XMVector3Normalize(XMVector3TransformNormal(rayDirection, objectMat_Inverse));
|
||||
|
||||
if (mesh.IsSkinned())
|
||||
{
|
||||
const ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID);
|
||||
|
||||
for (size_t vertexI = 0; vertexI < mesh.vertex_positions.size(); ++vertexI)
|
||||
{
|
||||
XMVECTOR pos = XMLoadFloat3(&mesh.vertex_positions[vertexI]);
|
||||
|
||||
const XMUINT4& ind = mesh.vertex_boneindices[vertexI];
|
||||
const XMFLOAT4& wei = mesh.vertex_boneweights[vertexI];
|
||||
|
||||
XMMATRIX sump = XMLoadFloat4x4(&armature.skinningMatrices[ind.x]) * wei.x;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind.y]) * wei.y;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind.z]) * wei.z;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind.w]) * wei.w;
|
||||
|
||||
_vertices[i] = XMVector3Transform(pos, sump);
|
||||
}
|
||||
}
|
||||
else if (mesh.IsDynamicVB())
|
||||
{
|
||||
//for (size_t i = 0; i < mesh.vertices_Transformed_POS.size(); ++i)
|
||||
//{
|
||||
// _vertices[i] = mesh.vertices_Transformed_POS[i].LoadPOS();
|
||||
//}
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < mesh.vertex_positions.size(); ++i)
|
||||
{
|
||||
_vertices[i] = XMLoadFloat3(&mesh.vertex_positions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int subsetCounter = 0;
|
||||
for (auto& subset : mesh.subsets)
|
||||
{
|
||||
@@ -7932,15 +7886,56 @@ wiRenderer::RayIntersectWorldResult wiRenderer::RayIntersectWorld(const RAY& ray
|
||||
uint32_t i0 = mesh.indices[subset.indexOffset + i + 0];
|
||||
uint32_t i1 = mesh.indices[subset.indexOffset + i + 1];
|
||||
uint32_t i2 = mesh.indices[subset.indexOffset + i + 2];
|
||||
|
||||
XMVECTOR p0 = XMLoadFloat3(&mesh.vertex_positions[i0]);
|
||||
XMVECTOR p1 = XMLoadFloat3(&mesh.vertex_positions[i1]);
|
||||
XMVECTOR p2 = XMLoadFloat3(&mesh.vertex_positions[i2]);
|
||||
|
||||
if (mesh.IsSkinned())
|
||||
{
|
||||
const ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID);
|
||||
|
||||
const XMUINT4& ind0 = mesh.vertex_boneindices[i0];
|
||||
const XMUINT4& ind1 = mesh.vertex_boneindices[i1];
|
||||
const XMUINT4& ind2 = mesh.vertex_boneindices[i2];
|
||||
|
||||
const XMFLOAT4& wei0 = mesh.vertex_boneweights[i0];
|
||||
const XMFLOAT4& wei1 = mesh.vertex_boneweights[i1];
|
||||
const XMFLOAT4& wei2 = mesh.vertex_boneweights[i2];
|
||||
|
||||
XMMATRIX sump;
|
||||
|
||||
sump = XMLoadFloat4x4(&armature.skinningMatrices[ind0.x]) * wei0.x;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind0.y]) * wei0.y;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind0.z]) * wei0.z;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind0.w]) * wei0.w;
|
||||
|
||||
p0 = XMVector3Transform(p0, sump);
|
||||
|
||||
sump = XMLoadFloat4x4(&armature.skinningMatrices[ind1.x]) * wei1.x;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind1.y]) * wei1.y;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind1.z]) * wei1.z;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind1.w]) * wei1.w;
|
||||
|
||||
p1 = XMVector3Transform(p1, sump);
|
||||
|
||||
sump = XMLoadFloat4x4(&armature.skinningMatrices[ind2.x]) * wei2.x;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind2.y]) * wei2.y;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind2.z]) * wei2.z;
|
||||
sump += XMLoadFloat4x4(&armature.skinningMatrices[ind2.w]) * wei2.w;
|
||||
|
||||
p2 = XMVector3Transform(p2, sump);
|
||||
}
|
||||
|
||||
float distance;
|
||||
if (TriangleTests::Intersects(rayOrigin_local, rayDirection_local, _vertices[i0], _vertices[i1], _vertices[i2], distance))
|
||||
if (TriangleTests::Intersects(rayOrigin_local, rayDirection_local, p0, p1, p2, distance))
|
||||
{
|
||||
XMVECTOR pos = XMVector3Transform(XMVectorAdd(rayOrigin_local, rayDirection_local*distance), objectMat);
|
||||
distance = wiMath::Distance(pos, rayOrigin);
|
||||
|
||||
if (distance < result.distance)
|
||||
{
|
||||
XMVECTOR nor = XMVector3Normalize(XMVector3TransformNormal(XMVector3Normalize(XMVector3Cross(XMVectorSubtract(_vertices[i2], _vertices[i1]), XMVectorSubtract(_vertices[i1], _vertices[i0]))), objectMat));
|
||||
XMVECTOR nor = XMVector3Normalize(XMVector3TransformNormal(XMVector3Normalize(XMVector3Cross(XMVectorSubtract(p2, p1), XMVectorSubtract(p1, p0))), objectMat));
|
||||
|
||||
result.entity = entity;
|
||||
XMStoreFloat3(&result.position, pos);
|
||||
|
||||
@@ -32,9 +32,30 @@ namespace wiSceneSystem
|
||||
}
|
||||
void TransformComponent::UpdateParentedTransform(const TransformComponent& parent, const XMFLOAT4X4& inverseParentBindMatrix)
|
||||
{
|
||||
dirty = true;
|
||||
XMMATRIX W;
|
||||
|
||||
XMMATRIX W = XMLoadFloat4x4(&world);
|
||||
// Normally, every transform would be NOT dirty at this point, but...
|
||||
|
||||
if (parent.dirty)
|
||||
{
|
||||
// If parent is dirty, that means it was tagged by animation system...
|
||||
dirty = true;
|
||||
|
||||
W = XMLoadFloat4x4(&world);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it is not dirty, then we still need to propagate parent's matrix to this,
|
||||
// because every transform is marked as NOT dirty at the end of transform update system
|
||||
// but we look up the local matrix instead, because world matrix might contain
|
||||
// results from previous run of the hierarchy system...
|
||||
XMVECTOR S_local = XMLoadFloat3(&scale_local);
|
||||
XMVECTOR R_local = XMLoadFloat4(&rotation_local);
|
||||
XMVECTOR T_local = XMLoadFloat3(&translation_local);
|
||||
W = XMMatrixScalingFromVector(S_local) *
|
||||
XMMatrixRotationQuaternion(R_local) *
|
||||
XMMatrixTranslationFromVector(T_local);
|
||||
}
|
||||
|
||||
XMMATRIX W_parent = XMLoadFloat4x4(&parent.world);
|
||||
XMMATRIX B = XMLoadFloat4x4(&inverseParentBindMatrix);
|
||||
@@ -267,15 +288,15 @@ namespace wiSceneSystem
|
||||
|
||||
// vertexBuffer - POSITION + NORMAL + SUBSETINDEX:
|
||||
{
|
||||
std::vector<uint8_t> vertex_subsetindices(vertex_positions.size());
|
||||
|
||||
std::unordered_map<uint32_t, uint32_t> subsetIndicesLUT;
|
||||
uint32_t subsetCounter = 0;
|
||||
for (auto& subset : subsets)
|
||||
{
|
||||
for (uint32_t i = 0; i < subset.indexCount; ++i)
|
||||
{
|
||||
uint32_t index = indices[subset.indexOffset + i];
|
||||
subsetIndicesLUT[index] = subsetCounter;
|
||||
vertex_subsetindices[index] = subsetCounter;
|
||||
}
|
||||
subsetCounter++;
|
||||
}
|
||||
@@ -284,9 +305,9 @@ namespace wiSceneSystem
|
||||
for (size_t i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
const XMFLOAT3& pos = vertex_positions[i];
|
||||
XMFLOAT3& nor = vertex_normals[i];
|
||||
XMFLOAT3& nor = vertex_normals.empty() ? XMFLOAT3(1, 1, 1) : vertex_normals[i];
|
||||
XMStoreFloat3(&nor, XMVector3Normalize(XMLoadFloat3(&nor)));
|
||||
uint32_t subsetIndex = subsetIndicesLUT[(uint32_t)i];
|
||||
uint32_t subsetIndex = vertex_subsetindices[i];
|
||||
vertices[i].FromFULL(pos, nor, subsetIndex);
|
||||
|
||||
_min = wiMath::Min(_min, pos);
|
||||
@@ -358,6 +379,7 @@ namespace wiSceneSystem
|
||||
}
|
||||
|
||||
// vertexBuffer - TEXCOORDS
|
||||
if(!vertex_texcoords.empty())
|
||||
{
|
||||
std::vector<Vertex_TEX> vertices(vertex_texcoords.size());
|
||||
for (size_t i = 0; i < vertices.size(); ++i)
|
||||
@@ -1164,7 +1186,7 @@ namespace wiSceneSystem
|
||||
|
||||
TransformComponent& transform = *transforms.GetComponent(channel.target);
|
||||
|
||||
if (channel.mode == AnimationComponent::AnimationChannel::Mode::STEP || (keyLeft == 0 && keyRight == 0))
|
||||
if (channel.mode == AnimationComponent::AnimationChannel::Mode::STEP || keyLeft == keyRight)
|
||||
{
|
||||
// Nearest neighbor method (snap to left):
|
||||
switch (channel.type)
|
||||
|
||||
Reference in New Issue
Block a user