Пример #1
0
        internal void UpdateExtraParams()
        {
            lock (m_ExtraParamsLock)
            {
                int  i                = 0;
                int  limitedi         = 0;
                uint totalBytesLength = 1;
                uint extraParamsNum   = 0;

                uint limitedTotalBytesLength = 1;
                uint limitedExtraParamsNum   = 0;

                var             flexi          = m_Part.Flexible;
                var             light          = m_Part.PointLight;
                var             proj           = Projection;
                var             shape          = m_Part.Shape;
                var             emesh          = m_Part.ExtendedMesh;
                bool            isFlexible     = flexi.IsFlexible;
                bool            isSculpt       = shape.Type == PrimitiveShapeType.Sculpt;
                ObjectGroup     objectGroup    = m_Part.ObjectGroup;
                bool            isFullLight    = light.IsLight;
                AttachmentPoint attachPoint    = objectGroup?.AttachPoint ?? AttachmentPoint.NotAttached;
                bool            isLimitedLight = isFullLight &&
                                                 (!m_Part.IsAttachmentLightsDisabled || !IsPrivateAttachmentOrNone(attachPoint)) &&
                                                 (!m_Part.IsFacelightDisabled || (attachPoint != AttachmentPoint.LeftHand && attachPoint != AttachmentPoint.RightHand)) &&
                                                 (!m_Part.IsUnattachedLightsDisabled || attachPoint != AttachmentPoint.NotAttached);
                bool isProjecting = proj.IsProjecting;
                ExtendedMeshParams.MeshFlags emeshFlags = emesh.Flags;
                if (isFlexible)
                {
                    ++extraParamsNum;
                    totalBytesLength += 16;
                    totalBytesLength += 2 + 4;
                }

                if (isSculpt)
                {
                    ++extraParamsNum;
                    totalBytesLength += 17;
                    totalBytesLength += 2 + 4;
                }

                if (isProjecting)
                {
                    ++extraParamsNum;
                    totalBytesLength += 28;
                    totalBytesLength += 2 + 4;
                }

                if (emeshFlags != ExtendedMeshParams.MeshFlags.None)
                {
                    ++extraParamsNum;
                    totalBytesLength += 4;
                    totalBytesLength += 2 + 4;
                }

                limitedExtraParamsNum   = extraParamsNum;
                limitedTotalBytesLength = totalBytesLength;

                if (isLimitedLight)
                {
                    ++limitedExtraParamsNum;
                    limitedTotalBytesLength += 16;
                    limitedTotalBytesLength += 2 + 4;
                }

                if (isFullLight)
                {
                    ++extraParamsNum;
                    totalBytesLength += 16;
                    totalBytesLength += 2 + 4;
                }

                var updatebytes        = new byte[totalBytesLength];
                var updatebyteslimited = new byte[limitedTotalBytesLength];
                updatebyteslimited[limitedi++] = (byte)limitedExtraParamsNum;
                updatebytes[i++] = (byte)extraParamsNum;

                if (isFlexible)
                {
                    updatebytes[i++] = FlexiEP % 256;
                    updatebytes[i++] = FlexiEP / 256;

                    updatebytes[i++] = 16;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;

                    updatebytes[i++] = (byte)((byte)((byte)(flexi.Tension * 10.01f) & 0x7F) | (byte)((flexi.Softness & 2) << 6));
                    updatebytes[i++] = (byte)((byte)((byte)(flexi.Friction * 10.01f) & 0x7F) | (byte)((flexi.Softness & 1) << 7));
                    updatebytes[i++] = (byte)((flexi.Gravity + 10.0f) * 10.01f);
                    updatebytes[i++] = (byte)(flexi.Wind * 10.01f);
                    flexi.Force.ToBytes(updatebytes, i);
                    i += 12;
                }

                if (isSculpt)
                {
                    updatebytes[i++] = SculptEP % 256;
                    updatebytes[i++] = SculptEP / 256;
                    updatebytes[i++] = 17;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    shape.SculptMap.ToBytes(updatebytes, i);
                    i += 16;
                    updatebytes[i++] = (byte)shape.SculptType;
                }

                Buffer.BlockCopy(updatebytes, 1, updatebyteslimited, 1, i - 1);
                limitedi = i;

                if (isFullLight)
                {
                    updatebytes[i++] = LightEP % 256;
                    updatebytes[i++] = LightEP / 256;
                    updatebytes[i++] = 16;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    Buffer.BlockCopy(light.LightColor.AsByte, 0, updatebytes, i, 3);

                    updatebytes[i + 3] = (byte)(light.Intensity * 255f);
                    i += 4;
                    ConversionMethods.Float2LEBytes((float)light.Radius, updatebytes, i);
                    i += 4;
                    ConversionMethods.Float2LEBytes((float)light.Cutoff, updatebytes, i);
                    i += 4;
                    ConversionMethods.Float2LEBytes((float)light.Falloff, updatebytes, i);
                    i += 4;
                }

                if (isLimitedLight)
                {
                    updatebyteslimited[limitedi++] = LightEP % 256;
                    updatebyteslimited[limitedi++] = LightEP / 256;
                    updatebyteslimited[limitedi++] = 16;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = 0;
                    Buffer.BlockCopy(light.LightColor.AsByte, 0, updatebyteslimited, limitedi, 3);

                    double intensity = light.Intensity;
                    double radius    = light.Radius;

                    if (attachPoint == AttachmentPoint.NotAttached)
                    {
                        intensity = Math.Min(m_Part.UnattachedLightLimitIntensity, intensity);
                        radius    = Math.Min(m_Part.UnattachedLightLimitRadius, radius);
                    }
                    else if (IsPrivateAttachmentOrNone(attachPoint))
                    {
                        /* skip these as they are anyways hidden from anyone else */
                    }
                    else
                    {
                        if (attachPoint != AttachmentPoint.LeftHand &&
                            attachPoint != AttachmentPoint.RightHand)
                        {
                            intensity = Math.Min(m_Part.FacelightLimitIntensity, intensity);
                            radius    = Math.Min(m_Part.FacelightLimitRadius, radius);
                        }
                        intensity = Math.Min(m_Part.AttachmentLightLimitIntensity, intensity);
                        radius    = Math.Min(m_Part.AttachmentLightLimitRadius, radius);
                    }

                    updatebyteslimited[limitedi + 3] = (byte)(intensity * 255f);
                    limitedi += 4;
                    ConversionMethods.Float2LEBytes((float)light.Radius, updatebyteslimited, limitedi);
                    limitedi += 4;
                    ConversionMethods.Float2LEBytes((float)light.Cutoff, updatebyteslimited, limitedi);
                    limitedi += 4;
                    ConversionMethods.Float2LEBytes((float)light.Falloff, updatebyteslimited, limitedi);
                    limitedi += 4;
                }

                if (isProjecting)
                {
                    /* full block */
                    updatebytes[i++] = (ProjectionEP % 256);
                    updatebytes[i++] = (ProjectionEP / 256);
                    updatebytes[i++] = 28;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    proj.ProjectionTextureID.ToBytes(updatebytes, i);
                    i += 16;
                    ConversionMethods.Float2LEBytes((float)proj.ProjectionFOV, updatebytes, i);
                    i += 4;
                    ConversionMethods.Float2LEBytes((float)proj.ProjectionFocus, updatebytes, i);
                    i += 4;
                    ConversionMethods.Float2LEBytes((float)proj.ProjectionAmbience, updatebytes, i);

                    /* limited block */
                    updatebyteslimited[limitedi++] = (ProjectionEP % 256);
                    updatebyteslimited[limitedi++] = (ProjectionEP / 256);
                    updatebyteslimited[limitedi++] = 28;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = 0;
                    proj.ProjectionTextureID.ToBytes(updatebyteslimited, limitedi);
                    limitedi += 16;
                    ConversionMethods.Float2LEBytes((float)proj.ProjectionFOV, updatebytes, limitedi);
                    limitedi += 4;
                    ConversionMethods.Float2LEBytes((float)proj.ProjectionFocus, updatebytes, limitedi);
                    limitedi += 4;
                    ConversionMethods.Float2LEBytes((float)proj.ProjectionAmbience, updatebytes, limitedi);
                }

                if (emeshFlags != ExtendedMeshParams.MeshFlags.None)
                {
                    /* full block */
                    updatebytes[i++] = (ExtendedMeshEP % 256);
                    updatebytes[i++] = (ExtendedMeshEP / 256);
                    updatebytes[i++] = 4;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = 0;
                    updatebytes[i++] = (byte)(((uint)emeshFlags) & 0xFF);
                    updatebytes[i++] = (byte)((((uint)emeshFlags) >> 8) & 0xFF);
                    updatebytes[i++] = (byte)((((uint)emeshFlags) >> 16) & 0xFF);
                    updatebytes[i++] = (byte)((((uint)emeshFlags) >> 24) & 0xFF);

                    /* limited block */
                    updatebyteslimited[limitedi++] = (ExtendedMeshEP % 256);
                    updatebyteslimited[limitedi++] = (ExtendedMeshEP / 256);
                    updatebyteslimited[limitedi++] = 4;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = 0;
                    updatebyteslimited[limitedi++] = (byte)(((uint)emeshFlags) & 0xFF);
                    updatebyteslimited[limitedi++] = (byte)((((uint)emeshFlags) >> 8) & 0xFF);
                    updatebyteslimited[limitedi++] = (byte)((((uint)emeshFlags) >> 16) & 0xFF);
                    updatebyteslimited[limitedi++] = (byte)((((uint)emeshFlags) >> 24) & 0xFF);
                }

                m_ExtraParamsBytes             = updatebytes;
                m_ExtraParamsBytesLimitedLight = updatebyteslimited;
            }
        }