diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-09 15:52:10 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-09 15:52:10 +0000 |
commit | c8b58a46e4f97791f81500006e464a94d68c8c12 (patch) | |
tree | 8991b7d38e19d9808ef273049a57c7338f4122d2 /o3d/import | |
parent | 1b91f510fdda3d6e764e0476df5a82c64ae2975e (diff) | |
download | chromium_src-c8b58a46e4f97791f81500006e464a94d68c8c12.zip chromium_src-c8b58a46e4f97791f81500006e464a94d68c8c12.tar.gz chromium_src-c8b58a46e4f97791f81500006e464a94d68c8c12.tar.bz2 |
This CL makes the collada importer handle skinned data
better.
Specifically, it takes the original VertexBuffer and
splits it. One VertexBuffer contains the parts fields
that get skinned. (POSITION, NORMAL, etc...) The other
VertexBuffer contains the fields that don't get Skinned.
(COLOR, TEXCOORD, etc...)
That way instancing you can share the non-skinned
VertexBuffer.
The next step is to not serialize the skinned
VertexBuffer's contents.
Review URL: http://codereview.chromium.org/118156
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17942 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/import')
-rw-r--r-- | o3d/import/cross/collada.cc | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/o3d/import/cross/collada.cc b/o3d/import/cross/collada.cc index b62ae8f..64d39fc 100644 --- a/o3d/import/cross/collada.cc +++ b/o3d/import/cross/collada.cc @@ -1378,8 +1378,23 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, Matrix4 matrix(bind_shape_matrix); // Copy shape->primitive buffers. + // Here we need to also split the original vertex buffer. The issue is + // the original VertexBuffer might contain POSITION, NORMAL, TEXCOORD, + // COLOR. Of those, only POSITION and NORMAL are copied to the SourceBuffer. + // The VertexBuffer still contains POSITON, NORMAL, TEXCOORD, and COLOR so + // two issues come up + // + // 1) If we serialize that VertexBuffer, POSITION and NORMAL are stored + // twice. Once in the SourceBuffer, again in the VertexBuffer. That's a lot + // of data to download just to throw it away. + // + // 2) If we want to instance the skin we'll need to make a new VertexBuffer + // so we can store the skinned vertices for the second instance. But we'd + // like to share the COLOR and TEXCOORDS. To do that they need to be in + // a separate VertexBuffer. StreamBank* stream_bank = primitive->stream_bank(); SourceBuffer* buffer = pack_->Create<SourceBuffer>(); + VertexBuffer* shared_buffer = pack_->Create<VertexBuffer>(); const StreamParamVector& source_stream_params = stream_bank->vertex_stream_params(); std::vector<Field*> new_fields(source_stream_params.size(), NULL); @@ -1387,6 +1402,7 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) { const Stream& source_stream = source_stream_params[ii]->stream(); const Field& field = source_stream.field(); + bool copied = false; if (field.IsA(FloatField::GetApparentClass()) && (field.num_components() == 3 || field.num_components() == 4)) { @@ -1395,6 +1411,7 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, case Stream::NORMAL: case Stream::BINORMAL: case Stream::TANGENT: { + copied = true; unsigned num_source_components = field.num_components(); unsigned num_source_vertices = source_stream.GetMaxVertices(); if (num_source_vertices != num_vertices) { @@ -1410,9 +1427,15 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, } } } + if (!copied) { + // It's a shared field, copy it to the shared buffer. + new_fields[ii] = shared_buffer->CreateField(field.GetClass(), + field.num_components()); + } } - if (!buffer->AllocateElements(num_vertices)) { + if (!buffer->AllocateElements(num_vertices) || + !shared_buffer->AllocateElements(num_vertices)) { O3D_ERROR(service_locator_) << "Failed to allocate destination vertex buffer"; return NULL; @@ -1421,6 +1444,7 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) { const Stream& source_stream = source_stream_params[ii]->stream(); const Field& field = source_stream.field(); + bool copied = false; if (field.IsA(FloatField::GetApparentClass()) && (field.num_components() == 3 || field.num_components() == 4)) { @@ -1429,6 +1453,7 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, case Stream::NORMAL: case Stream::BINORMAL: case Stream::TANGENT: { + copied = true; unsigned num_source_components = field.num_components(); Field* new_field = new_fields[ii]; @@ -1485,6 +1510,15 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, } } } + if (!copied) { + Field* new_field = new_fields[ii]; + new_field->Copy(field); + field.buffer()->RemoveField(&source_stream.field()); + stream_bank->SetVertexStream(source_stream.semantic(), + source_stream.semantic_index(), + new_field, + 0); + } } } return shape; |