Beispiel #1
0
    public void Render(IGameViewport viewport, IAnimatedModel model, AnimatedModelParams animParams, IList <Light3d> lights,
                       MdfRenderOverrides materialOverrides = null)
    {
        var renderData = GetOrCreateState(model);

        var materialIds = model.GetSubmeshes();

        for (var i = 0; i < materialIds.Length; ++i)
        {
            var material = materialIds[i];
            var submesh  = animParams.rotation3d ? model.GetSubmeshForParticles(animParams, i) : model.GetSubmesh(animParams, i);

            // Usually this should not happen, since it means there's
            // an unbound replacement material
            if (material == null)
            {
                continue;
            }

            material.Bind(viewport, mDevice, lights, materialOverrides);

            // Do we have to recalculate the normals?
            if (material.GetSpec().recalculateNormals)
            {
                RecalcNormals(
                    submesh.VertexCount,
                    submesh.Positions,
                    submesh.Normals,
                    submesh.PrimitiveCount,
                    submesh.Indices
                    );
            }

            var submeshData = GetSubmeshData(renderData, i, submesh);
            submeshData.binding.Resource.Bind();

            mDevice.SetIndexBuffer(submeshData.idxBuffer);
            mDevice.DrawIndexed(PrimitiveType.TriangleList,
                                submesh.VertexCount,
                                submesh.PrimitiveCount * 3);
        }
    }
Beispiel #2
0
    public static AnimatedModelParams GetAnimParams(this GameObject obj)
    {
        var result = new AnimatedModelParams();

        result.scale = obj.GetScalePercent() / 100.0f;

        // Special case for equippable items
        if (obj.type.IsEquipment())
        {
            var itemFlags = obj.GetItemFlags();
            if (itemFlags.HasFlag(ItemFlag.DRAW_WHEN_PARENTED))
            {
                var parent = GameSystems.Item.GetParent(obj);
                if (parent != null)
                {
                    result.scale *= parent.GetScalePercent() / 100.0f;

                    result.attachedBoneName = GameSystems.Item.GetAttachBone(obj);
                    if (result.attachedBoneName != null)
                    {
                        var parentLoc = parent.GetLocationFull();
                        result.x       = parentLoc.location.locx;
                        result.y       = parentLoc.location.locy;
                        result.offsetX = parentLoc.off_x;
                        result.offsetY = parentLoc.off_y;

                        var parentDepth = GameSystems.Height.GetDepth(parentLoc);
                        var offsetZ     = parent.OffsetZ;
                        result.offsetZ = offsetZ - parentDepth;

                        result.rotation      = parent.Rotation;
                        result.rotationPitch = parent.RotationPitch;
                        result.parentAnim    = parent.GetOrCreateAnimHandle();

                        return(result);
                    }
                }
            }
        }

        var loc = obj.GetLocationFull();

        result.x       = loc.location.locx;
        result.y       = loc.location.locy;
        result.offsetX = loc.off_x;
        result.offsetY = loc.off_y;

        var   flags = obj.GetFlags();
        sbyte depth = 0;

        if (!flags.HasFlag(ObjectFlag.NOHEIGHT))
        {
            depth = GameSystems.Height.GetDepth(loc);
        }

        result.offsetZ       = obj.OffsetZ - depth;
        result.rotation      = obj.Rotation;
        result.rotationPitch = obj.RotationPitch;

        return(result);
    }
Beispiel #3
0
    // TODO: Separate logic+rendering
    public void AdvanceAndRender(
        IGameViewport viewport,
        GameObject giantFrog,
        AnimatedModelParams animParams,
        IAnimatedModel model,
        IList <Light3d> lights,
        float alpha)
    {
        var grappleState = GetGrappleState(giantFrog);

        if (grappleState.state == 0)
        {
            return;
        }

        model.GetBoneWorldMatrixByName(animParams, "Tongue_Ref", out var worldMatrixFrog);

        var   grappledOpponent = GetGrappledOpponent(giantFrog);
        float tongueLength, tonguePosX, tonguePosZ;

        if (grappledOpponent != null)
        {
            var opponentModel      = grappledOpponent.GetOrCreateAnimHandle();
            var opponentAnimParams = grappledOpponent.GetAnimParams();
            opponentModel.GetBoneWorldMatrixByName(opponentAnimParams, "Bip01 Spine1", out var worldMatrixOpponent);

            tonguePosX = worldMatrixOpponent.M41;
            tonguePosZ = worldMatrixOpponent.M43;

            var tongueDirX = worldMatrixOpponent.M41 - worldMatrixFrog.M41;
            var tongueDirY = worldMatrixOpponent.M42 - worldMatrixFrog.M42;
            var tongueDirZ = worldMatrixOpponent.M43 - worldMatrixFrog.M43;
            tongueLength        = MathF.Sqrt(tongueDirX * tongueDirX + tongueDirY * tongueDirY + tongueDirZ * tongueDirZ);
            worldMatrixFrog.M31 = tongueDirX / tongueLength;
            worldMatrixFrog.M32 = tongueDirY / tongueLength;
            worldMatrixFrog.M33 = tongueDirZ / tongueLength;
            if (tongueLength > 0)
            {
                tongueLength -= 6.0f;
            }
        }
        else
        {
            tongueLength = 120.0f;
            tonguePosX   = worldMatrixFrog.M31 * 120.0f + worldMatrixFrog.M41;
            tonguePosZ   = worldMatrixFrog.M33 * 120.0f + worldMatrixFrog.M43;
        }

        switch (grappleState.state)
        {
        // This state seems to mean . Extending tongue to full length
        case 1:
            grappleState.currentLength += locXY.INCH_PER_TILE;
            if (grappleState.currentLength > tongueLength)
            {
                grappleState.state         = 2;
                grappleState.currentLength = tongueLength;
            }

            break;

        // This state seems to mean . Retracting tongue
        case 2:
            grappleState.currentLength -= locXY.INCH_PER_TILE;
            if (grappleState.currentLength <= 0)
            {
                grappleState.state         = 0;
                grappleState.currentLength = 0;
            }

            break;

        case 3:
            grappleState.currentLength += locXY.INCH_PER_TILE;
            if (grappleState.currentLength > tongueLength)
            {
                grappleState.state         = 4;
                grappleState.currentLength = tongueLength;
                var frogAnim = GameSystems.Critter.GetAnimId(giantFrog,
                                                             WeaponAnim.Special2);
                giantFrog.SetAnimId(frogAnim);

                var opponentAnim = GameSystems.Critter.GetAnimId(grappledOpponent,
                                                                 WeaponAnim.Panic);
                grappledOpponent.SetAnimId(opponentAnim);
            }

            break;

        case 4:
            // Maintain Tongue between frog and opponent without progressing
            grappleState.currentLength = tongueLength;
            break;

        case 5:
        case 6:
        {
            if (grappleState.state == 5)
            {
                grappleState.targetLength = tongueLength - 12.0f;
                if (grappleState.targetLength < 0)
                {
                    grappleState.targetLength = 0;
                }

                grappleState.state = 6;
            }

            grappleState.currentLength = grappleState.currentLength - locXY.INCH_PER_HALFTILE;
            // Move the opponent closer to the frog
            float newX   = tonguePosX - worldMatrixFrog.M31 * locXY.INCH_PER_HALFTILE;
            float newZ   = tonguePosZ - worldMatrixFrog.M33 * locXY.INCH_PER_HALFTILE;
            var   newLoc = LocAndOffsets.FromInches(newX, newZ);
            GameSystems.MapObject.Move(grappledOpponent, newLoc);

            if (grappleState.currentLength < grappleState.targetLength)
            {
                newX   = worldMatrixFrog.M41 + grappleState.targetLength * worldMatrixFrog.M31;
                newZ   = worldMatrixFrog.M43 + grappleState.targetLength * worldMatrixFrog.M33;
                newLoc = LocAndOffsets.FromInches(newX, newZ);
                GameSystems.MapObject.Move(grappledOpponent, newLoc);
                grappleState.currentLength = grappleState.targetLength;
                grappleState.state         = 4;
            }
        }
        break;

        case 7:
        {
            grappleState.currentLength = grappleState.currentLength - locXY.INCH_PER_HALFTILE;
            // Move the opponent closer to the frog
            float newX   = tonguePosX - worldMatrixFrog.M31 * locXY.INCH_PER_HALFTILE;
            float newZ   = tonguePosZ - worldMatrixFrog.M33 * locXY.INCH_PER_HALFTILE;
            var   newLoc = LocAndOffsets.FromInches(newX, newZ);
            GameSystems.MapObject.Move(grappledOpponent, newLoc);

            if (grappleState.currentLength < 0)
            {
                newX   = worldMatrixFrog.M41;
                newZ   = worldMatrixFrog.M43;
                newLoc = LocAndOffsets.FromInches(newX, newZ);
                GameSystems.MapObject.Move(grappledOpponent, newLoc);
                GameSystems.ObjFade.FadeTo(grappledOpponent, 0, 0, 16, 0);
                grappleState.currentLength = 0;
                grappleState.state         = 0;

                // Probably the swallow animation
                var animId = GameSystems.Critter.GetAnimId(giantFrog, WeaponAnim.Special3);
                giantFrog.SetAnimId(animId);
            }
        }
        break;

        default:
            break;
        }

        // Update to the new grapple state
        SetGrappleState(giantFrog, grappleState);

        // The directional vector of the tongue ref point on the frog
        var tongueUp    = worldMatrixFrog.GetRow(0).ToVector3();
        var tongueRight = worldMatrixFrog.GetRow(1).ToVector3();
        var tongueDir   = worldMatrixFrog.GetRow(2).ToVector3();
        var tonguePos   = worldMatrixFrog.GetRow(3).ToVector3();

        RenderTongue(viewport, grappleState, tongueDir, tongueUp, tongueRight, tonguePos, lights, alpha);
    }