Exemplo n.º 1
0
        public static Dictionary <int, CgfLoader> CreateBrushLstCgfLoaderMap(
            DirManager meshesDir, BrushLstLoader brushlst)
        {
            var cgfMap = new Dictionary <int, CgfLoader>();

            foreach (var brushInfo in brushlst.brushInfoList)
            {
                if (!meshesDir.Exists(brushInfo.filename))
                {
                    Log.WriteLine("**Model not found: " + brushInfo.filename);
                    continue;
                }

                using (var cgfStream = meshesDir.OpenFile(brushInfo.filename))
                {
                    var c = new CgfLoader(cgfStream);
                    cgfMap.Add(brushInfo.brushInfoIndex, c);
                }
            }
            return(cgfMap);
        }
Exemplo n.º 2
0
        // hack: creates a new cgf at the specified time in ticks.
        // uses the controllers to modify the original transforms.
        // this loads exact keyframe values, curves are not interpolated.
        public CgfLoader CloneAtTime(int ticks)
        {
            // TODO - check loop type.
            // TODO - check ticks is not greater than global range - need to load timing chunk.
            // TODO - validate keyframe start times are ascending and within global range.
            // TODO - validate controller type. TCB3 for pos, scale, TCBQ for rot, others unexpected...
            // TODO - validate cga vs cgf... some doors have .cgf extension...

            CgfLoader clone;

            using (var stream = new MemoryStream(m_originalFileBytes))
                clone = new CgfLoader(stream);

            //Debug.WriteLine("cga");
            //Debug.WriteLine("-----------------------------------------------");
            foreach (var node in clone.Nodes)
            {
                if (node.positionControllerId != -1)
                {
                    var cd = clone.GetControllerData(node.positionControllerId, ControllerType.TCB3);
                    for (int i = cd.Count - 1; i >= 0; i--)
                    {
                        if (ticks >= cd[i].StartTicks)
                        {
                            node.position.X = cd[i].Params[0];
                            node.position.Y = cd[i].Params[1];
                            node.position.Z = cd[i].Params[2];
                            break;
                        }
                    }
                }
                //Debug.WriteLine("node");
                //Debug.WriteLine("");
                if (node.rotationControllerId != -1)
                {
                    // Note: collision meshes usually have simpler transforms, for example most have no rotation,
                    // so bugs here have less chance of affecting geo data.

                    // BUG: idraksha - idraksha_door\IDraksha5f_eventbridge01a.cga - rotated incorrectly, but has no collision data.

                    var cd = clone.GetControllerData(node.rotationControllerId, ControllerType.TCBQ);

                    if (cd.Count <= 1)
                    {
                        // BUG: doors in theo lab have nodes with broken rotations.
                        // see librarydoor_04d controller=12 values: {0, 45 deg, 45 deg, 180 deg}
                        // they appear in a 1-key set, so ignoring those for now.
                        goto skipRot;
                    }

                    var rot = new Quaternion(node.rotQuat[0], node.rotQuat[1], node.rotQuat[2], node.rotQuat[3]);

                    int curTime = 0;
                    for (int i = 0; i < cd.Count; i++)
                    {
                        // params 4 through 8: t,c,b,ein,eout
                        //if (cd[i].Params[4] != 0 || cd[i].Params[5] != 0 || cd[i].Params[6] != 0 || cd[i].Params[7] != 0 || cd[i].Params[8] != 0)
                        //    throw new InvalidOperationException("expected zeroes");

                        if (!(Math.Abs(cd[i].Params[0] - 1) < 0.00001 &&
                              Math.Abs(cd[i].Params[1]) < 0.00001 &&
                              Math.Abs(cd[i].Params[2]) < 0.00001 &&
                              Math.Abs(cd[i].Params[3]) < 0.00001))
                        {
                            rot *= Quaternion.CreateFromAxisAngle(
                                new Vector3(cd[i].Params[0], cd[i].Params[1], cd[i].Params[2]),
                                cd[i].Params[3]);
                        }

                        // Check if ticks ends before the next frame, or past the end
                        if ((i < cd.Count - 1 && ticks <= curTime + cd[i].StartTicks) || i == cd.Count - 1)
                        {
                            // stop and use this frame
                            node.rotQuat[0] = rot.X;
                            node.rotQuat[1] = rot.Y;
                            node.rotQuat[2] = rot.Z;
                            node.rotQuat[3] = rot.W;
                            break;
                        }
                    }
                    skipRot :;
                }

                if (node.scaleControllerId != -1)
                {
                    var cd = clone.GetControllerData(node.scaleControllerId, ControllerType.TCB3);
                    foreach (var d in cd)
                    {
                        if (d.Params[0] != 1 || d.Params[1] != 1 || d.Params[2] != 1)
                        {
                            node.scale.X *= d.Params[0];
                            node.scale.Y *= d.Params[1];
                            node.scale.Z *= d.Params[2];
                        }
                    }
                }
            }
            return(clone);
        }