many fixes

This commit is contained in:
turanszkij
2018-09-08 20:56:17 +01:00
parent 14425c70cc
commit a056ad0686
3 changed files with 128 additions and 117 deletions
+56 -62
View File
@@ -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
View File
@@ -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);
+29 -7
View File
@@ -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)