COLLADA: Support for alpha color in vertex data.

Many thanks to the original Author of this patch: Christian Aguilera

The COLLADA importer was silently ignoring the alpha component in the
vertex data.

The `stride` variable holds the component count (3 for RGB; 4 for RGBA),
and can be used for honouring the alpha channel in the vertex data.

Test plan:
- Open Blender.
- Clear the scene.
- Add a plane.
- Enter **Vertex Paint** mode.
- Switch to the **Erase Alpha** blending mode.
- Select a tone of gray.
- Turn strength down to less than 1
- Paint [some of] the vertices of the plane.
- Export project as a COLLADA file (`.dae`).
- Clear the scene.
- Re-import the COLLADA file again.
- Export the project again (with different name).

**Without** this patch, the second exported project will have lost the
alpha component in their vertex data:

```lang=xml, counterexample
<float_array id="Plane-mesh-colors-Col-array" count="24">1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1</float_array>
```

**With** the patch, the first and the second exported projects retain
the alpha values painted previously:

```lang=xml
<float_array id="Plane-mesh-colors-Col-array" count="24">1 1 1 1 1 1 1 0.5490196 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.5490196</float_array>
```

Reviewed By: cristian64, SonnyCampbell_Unity
Authored by: Christian Aguilera

Differential Revision: https://developer.blender.org/D14246
This commit is contained in:
Gaia Clary 2022-06-30 22:12:38 +02:00 committed by Gaia Clary
parent f18067aa03
commit 106d937a4e
Notes: blender-bot 2023-02-14 06:00:50 +01:00
Referenced by issue #88449: Blender LTS: Maintenance Task 2.93
Referenced by issue #88449, Blender LTS: Maintenance Task 2.93
1 changed files with 24 additions and 14 deletions

View File

@ -145,6 +145,27 @@ VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData &vdata) : mVData(&vda
{
}
template<typename T>
static void colladaAddColor(T values, MLoopCol *mloopcol, int v_index, int stride)
{
if (values->empty() || values->getCount() < (v_index + 1) * stride) {
fprintf(stderr,
"VCOLDataWrapper.getvcol(): Out of Bounds error: index %d points outside value "
"list of length %zd (with stride=%d) \n",
v_index,
values->getCount(),
stride);
return;
}
mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
if (stride == 4) {
mloopcol->a = unit_float_to_uchar_clamp((*values)[v_index * stride + 3]);
}
}
void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
{
int stride = mVData->getStride(0);
@ -155,25 +176,14 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
switch (mVData->getType()) {
case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: {
COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
if (values->empty() || values->getCount() <= (v_index * stride + 2)) {
return; /* XXX: need to create an error instead. */
}
mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
colladaAddColor<COLLADAFW::ArrayPrimitiveType<float> *>(values, mloopcol, v_index, stride);
} break;
case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: {
COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
if (values->empty() || values->getCount() <= (v_index * stride + 2)) {
return; /* XXX: need to create an error instead. */
}
mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
colladaAddColor<COLLADAFW::ArrayPrimitiveType<double> *>(values, mloopcol, v_index, stride);
} break;
default:
fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n");
}