Пример #1
0
void CollisionVolume::Init(const float3& scales, const float3& offsets, int vType, int tType, int pAxis)
{
    // assign these here, since we can be
    // called from outside the constructor
    primaryAxis = std::max(pAxis, 0) % COLVOL_NUM_AXES;
    volumeType  = std::max(vType, 0) % COLVOL_NUM_SHAPES;
    testType    = std::max(tType, 0) % COLVOL_NUM_HITTESTS;

    // allow defining a custom volume without using it for coldet
    disabled    = (scales.x < 0.0f || scales.y < 0.0f || scales.z < 0.0f);
    axisOffsets = offsets;

    // make sure none of the scales are ever negative
    // or zero; if the resulting vector is <1, 1, 1>,
    // then the unit / feature loaders will override
    // the (clone) scales with the model's radius
    SetAxisScales(std::max(1.0f, scales.x), std::max(1.0f, scales.y), std::max(1.0f, scales.z));

    if (volumeType == COLVOL_TYPE_ELLIPSOID) {
        // if all axes (or half-axes) are equal in scale,
        // volume is a sphere (a special-case ellipsoid)
        if ((streflop::fabsf(axisHScales.x - axisHScales.y) < EPS) &&
                (streflop::fabsf(axisHScales.y - axisHScales.z) < EPS)) {

            logOutput.Print(LOG_COLVOL, "auto-converting spherical COLVOL_TYPE_ELLIPSOID to COLVOL_TYPE_SPHERE");
            volumeType = COLVOL_TYPE_SPHERE;
        }
    }


    // secondaryAxes[0] = (primaryAxis + 1) % COLVOL_NUM_AXES;
    // secondaryAxes[1] = (primaryAxis + 2) % COLVOL_NUM_AXES;

    switch (primaryAxis) {
    case COLVOL_AXIS_X: {
        secondaryAxes[0] = COLVOL_AXIS_Y;
        secondaryAxes[1] = COLVOL_AXIS_Z;
    }
    break;
    case COLVOL_AXIS_Y: {
        secondaryAxes[0] = COLVOL_AXIS_X;
        secondaryAxes[1] = COLVOL_AXIS_Z;
    }
    break;
    case COLVOL_AXIS_Z: {
        secondaryAxes[0] = COLVOL_AXIS_X;
        secondaryAxes[1] = COLVOL_AXIS_Y;
    }
    break;
    }

    SetBoundingRadius();
}
Пример #2
0
void CollisionVolume::InitShape(
	const float3& scales,
	const float3& offsets,	
	const int vType,
	const int tType,
	const int pAxis)
{
	float3 clampedScales;

	// make sure none of the scales are ever negative or zero
	//
	// if the clamped vector is <1, 1, 1> (ie. all scales were <= 1.0f)
	// then we assume a "default volume" is wanted and the unit/feature
	// instances will be assigned spheres (of size model->radius)
	clampedScales.x = std::max(1.0f, scales.x);
	clampedScales.y = std::max(1.0f, scales.y);
	clampedScales.z = std::max(1.0f, scales.z);

	// assign these here, since we can be
	// called from outside the constructor
	volumeType    = std::max(vType, 0) % (COLVOL_TYPE_SPHERE + 1);
	volumeAxes[0] = std::max(pAxis, 0) % (COLVOL_AXIS_Z + 1);

	axisOffsets = offsets;
	useContHitTest = (tType == COLVOL_HITTEST_CONT);

	switch (volumeAxes[0]) {
		case COLVOL_AXIS_X: {
			volumeAxes[1] = COLVOL_AXIS_Y;
			volumeAxes[2] = COLVOL_AXIS_Z;
		} break;
		case COLVOL_AXIS_Y: {
			volumeAxes[1] = COLVOL_AXIS_X;
			volumeAxes[2] = COLVOL_AXIS_Z;
		} break;
		case COLVOL_AXIS_Z: {
			volumeAxes[1] = COLVOL_AXIS_X;
			volumeAxes[2] = COLVOL_AXIS_Y;
		} break;
	}

	// NOTE:
	//   ellipses are now ALWAYS auto-converted to boxes or
	//   to spheres depending on scale values, cylinders to
	//   base cylinders (ie. with circular cross-section)
	//
	//   we assume that if the volume-type is set to ellipse
	//   then its shape is largely anisotropic such that the
	//   conversion does not create too much of a difference
	//
	if (volumeType == COLVOL_TYPE_ELLIPSOID) {
		const float dxyAbs = math::fabsf(clampedScales.x - clampedScales.y);
		const float dyzAbs = math::fabsf(clampedScales.y - clampedScales.z);
		const float d12Abs = math::fabsf(clampedScales[volumeAxes[1]] - clampedScales[volumeAxes[2]]);

		if (dxyAbs < COLLISION_VOLUME_EPS && dyzAbs < COLLISION_VOLUME_EPS) {
			volumeType = COLVOL_TYPE_SPHERE;
		} else {
			if (d12Abs < COLLISION_VOLUME_EPS) {
				volumeType = COLVOL_TYPE_CYLINDER;
			} else {
				volumeType = COLVOL_TYPE_BOX;
			}
		}
	}
	if (volumeType == COLVOL_TYPE_CYLINDER) {
		clampedScales[volumeAxes[1]] = std::max(clampedScales[volumeAxes[1]], clampedScales[volumeAxes[2]]);
		clampedScales[volumeAxes[2]] =          clampedScales[volumeAxes[1]];
	}

	SetAxisScales(clampedScales);
	SetBoundingRadius();
}