summaryrefslogtreecommitdiffstats
path: root/o3d/import
diff options
context:
space:
mode:
authorgman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 15:52:10 +0000
committergman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 15:52:10 +0000
commitc8b58a46e4f97791f81500006e464a94d68c8c12 (patch)
tree8991b7d38e19d9808ef273049a57c7338f4122d2 /o3d/import
parent1b91f510fdda3d6e764e0476df5a82c64ae2975e (diff)
downloadchromium_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.cc36
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;