Example #1
0
        /** Load the KFB data for the selected animation, will return null if the animation does not exist in the KFB */
        private byte[] getKFBData(int animToUse)
        {
            if (kfb == null)
            {
                return(null);
            }
            if (kfbfile == null)
            {
                if (this.adb.filenameExists(this.kfb))
                {
                    kfbfile = NIFLoader.getNIF(this.kfb);
                }
                else
                {
                    return(null);
                }
                //Debug.Log("getting KFB: " + this.kfb);
            }
            /** Choose the right animation to load from the KFB file. Ideally we should use the KFM to know what index to use */
            for (int i = 0; i < kfbfile.numObjects; i += 4)
            {
                NiIntegerExtraData indexData = (NiIntegerExtraData)kfbfile.getObject(i);
                NiIntegerExtraData sizeData  = (NiIntegerExtraData)kfbfile.getObject(i + 1);
                NiBinaryExtraData  binData   = (NiBinaryExtraData)kfbfile.getObject(i + 2);
                NiBinaryExtraData  binData2  = (NiBinaryExtraData)kfbfile.getObject(i + 3);

                int animIdx = indexData.intExtraData;
                if (animIdx == animToUse)
                {
                    return(binData.getData());
                }
            }
            //Debug.LogError("[" + this.kfb + "] can't find data for anim[" + animToUse + "]");
            return(null);
        }
Example #2
0
    static public void linkBonesToMesh(NIFFile nf, GameObject skeletonRoot)
    {
        // Debug.Log("link bones to mesh[" + skeletonRoot.GetInstanceID() + "]");
        List <NiSkinningMeshModifier> skinMods = getSkinMods(nf);

        foreach (NiSkinningMeshModifier skinMod in skinMods)
        {
            if (skinMod != null)
            {
                List <Transform> bones     = new List <Transform>();
                List <Matrix4x4> bindPoses = new List <Matrix4x4>();

                NIFObject rootBoneNode = nf.getObject(skinMod.rootBoneLinkID);
                //Debug.Log("looking for root bone:" + rootBoneNode.name + " in skeleton root");
                Transform rootBone = skeletonRoot.transform.FindDeepChild(rootBoneNode.name);

                List <int> boneLinkIds = skinMod.boneLinkIDs;
                for (int boneIdx = 0; boneIdx < boneLinkIds.Count; boneIdx++)
                {
                    int       objId = boneLinkIds[boneIdx];
                    NIFObject ni    = nf.getObject(objId);
                    Transform t     = skeletonRoot.transform.FindDeepChild(ni.name);

                    if (t != null)
                    {
                        bones.Add(t);
                        NITransform nit = skinMod.m_pkSkinToBoneTransforms[boneIdx];
                        Matrix4x4   m   = toMat(nit.matrix).transpose;
                        bindPoses.Add(m);
                    }
                }

                NiMesh              mes          = getMeshForMod(nf, skinMod);
                Transform           meshObject   = skeletonRoot.transform.FindDeepChild(mes.name);
                SkinnedMeshRenderer meshRenderer = meshObject.GetComponent <SkinnedMeshRenderer>();
                meshRenderer.updateWhenOffscreen = true;
                //Debug.Log("found mesh renderer: " + meshRenderer.GetInstanceID() + " with bones:" + bones.Count);
                meshRenderer.rootBone             = rootBone;
                meshRenderer.bones                = bones.ToArray();
                meshRenderer.sharedMesh.bindposes = bindPoses.ToArray();
                meshRenderer.sharedMesh.RecalculateBounds();
            }
        }
    }
Example #3
0
    // Use this for initialization
    void Start()
    {
        AssetDatabase db = AssetDatabaseInst.DB;

        KFMFile kfm     = new KFMFile(new FileStream(@"C:\Users\Spikeles\Documents\NetBeansProjects\TelaraDBExplorer\TelaraDBEditorCore\human_female_medium.kfm", FileMode.Open, FileAccess.Read, FileShare.Read));
        NIFFile kfbfile = new NIFFile(new FileStream(@"C:\Users\Spikeles\Documents\NetBeansProjects\TelaraDBExplorer\TelaraDBEditorCore\human_female_2h_shared.kfb", FileMode.Open, FileAccess.Read, FileShare.Read));

        // 230, string -> index 2

        List <KFAnimation> anims = kfm.kfanimations;
        int maxAnimID            = 0;

        foreach (KFAnimation anim in anims)
        {
            maxAnimID = Mathf.Max(anim.id, maxAnimID);
            //Debug.Log(anim.id + ":" + anim.sequenceFilename + ":" + anim.sequencename);
        }
        Debug.Log("maxAnimID:" + maxAnimID);

        for (int i = 0; i < kfbfile.numObjects; i += 4)
        {
            NiIntegerExtraData indexData = (NiIntegerExtraData)kfbfile.getObject(i);
            NiIntegerExtraData sizeData  = (NiIntegerExtraData)kfbfile.getObject(i + 1);
            NiBinaryExtraData  binData   = (NiBinaryExtraData)kfbfile.getObject(i + 2);
            NiBinaryExtraData  binData2  = (NiBinaryExtraData)kfbfile.getObject(i + 3);
            KFAnimation        anim      = anims.DefaultIfEmpty(null).FirstOrDefault(a => a.id == indexData.intExtraData);
            if (anim != null)
            {
                Debug.Log("kfb[" + indexData.intExtraData + "] match => [" + anim.id + "]" + anim.sequenceFilename);
            }
            else
            {
                Debug.Log("kfb[" + indexData.intExtraData + "] nomatch");
            }
        }
        Debug.Log("kfb objs:" + kfbfile.numObjects / 4);
        Debug.Log("anims:" + anims.Count);
        //File.WriteAllBytes("human_female.kfb" + i + "_0", binData.getData());
        //File.WriteAllBytes("human_female.kfb" + i + "_1", binData2.getData());
    }
Example #4
0
 static private NiFloatsExtraData getFloatsExtraData(NIFFile nf, NiMesh mesh, string v)
 {
     foreach (int eid in mesh.extraDataIDs)
     {
         NIFObject obj = nf.getObject(eid);
         if (obj is NiFloatsExtraData)
         {
             NiFloatsExtraData fExtra = (NiFloatsExtraData)obj;
             if (fExtra.extraDataString.Equals(v))
             {
                 return(fExtra);
             }
         }
     }
     return(null);
 }
Example #5
0
    static private String[] getTextureIds(NIFFile nf, NiMesh mesh)
    {
        String[]            textureType;
        NiTexturingProperty texturingProperty = mesh.getTexturingProperty(nf);

        if (texturingProperty != null)
        {
            //Debug.Log("found texturing property for mesh " + mesh.name);
            textureType = new String[texturingProperty.shaderMapList.Count];
            foreach (int extraID in mesh.extraDataIDs)
            {
                NIFObject ni = nf.getObject(extraID);
                if (ni is NiIntegerExtraData)
                {
                    NiIntegerExtraData nied = (NiIntegerExtraData)ni;
                    if (nied.extraDataString != null)
                    {
                        if (nied.extraDataString.Contains("Texture"))
                        {
                            if (nied.intExtraData >= 0 && nied.intExtraData < textureType.Length)
                            {
                                textureType[nied.intExtraData] = nied.extraDataString;
                            }
                            else
                            {
                                //                                Debug.LogWarning("nied.intExtraData out of range:" + nied.intExtraData + " => " + textureType.Length);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            textureType = new String[255];
        }
        return(textureType);
    }
Example #6
0
        public void doFrame(float t)
        {
            if (skeletonRoot == null)
            {
                Debug.LogError("no skeleton root");
                return;
            }
            if (nifanimation == null || activeAnimation == -1)
            {
                setActiveAnimation(getIdleAnimIndex());
                if (nifanimation == null)
                {
                    return;
                }
            }
            //Debug.Log("using anim :" + this.nifanimation.)

            /** For each sequence, evaluate it with the current time and apply the result to the related bone */
            foreach (NiSequenceData data in nifanimation.nifSequences)
            {
                for (int i = 0; i < data.seqEvalIDList.Count; i++)
                {
                    int       evalID   = (int)data.seqEvalIDList[i];
                    NIFObject evalObjA = nifanimation.getObject(evalID);
                    if (nifanimation.getObject(evalID) is NiBSplineCompTransformEvaluator)
                    {
                        NiBSplineCompTransformEvaluator evalObj = (NiBSplineCompTransformEvaluator)evalObjA;
                        string     boneName = nifanimation.getStringFromTable(evalObj.m_kAVObjectName);
                        GameObject go;
                        // cache game objects for bones
                        boneMap.TryGetValue(boneName, out go);
                        if (go == null)
                        {
                            Transform bone = skeletonRoot.transform.FindDeepChild(boneName);
                            if (bone == null)
                            {
//                                Debug.LogWarning("unable to find bone in skeleton for " + boneName);
                                continue;
                            }
                            go = boneMap[boneName] = bone.gameObject;
                            //GameObject.Find(boneName);
                        }
                        if (go == null)
                        {
                            //                          Debug.Log("unable to get gameobject for bone " + boneName);
                            continue;
                        }
                        int splineDataIndex = evalObj.splineDataIndex;
                        int basisDataIndex  = evalObj.basisDataIndex;



                        if (splineDataIndex != -1 && basisDataIndex != -1)
                        {
                            NiBSplineData      splineObj = (NiBSplineData)nifanimation.getObject(splineDataIndex);
                            NiBSplineBasisData basisObj  = (NiBSplineBasisData)nifanimation.getObject(basisDataIndex);
                            if (evalObj.m_kRotCPHandle != 65535)
                            {
                                float[] afValues = new float[4];
                                // get the rotation values for the given time 't'
                                splineObj.getCompactValueDegree3(t, afValues, 4, basisObj, evalObj.m_kRotCPHandle,
                                                                 evalObj.m_afCompScalars[(int)NiBSplineCompTransformEvaluator.COMP_.ROTATION_OFFSET],
                                                                 evalObj.m_afCompScalars[(int)NiBSplineCompTransformEvaluator.COMP_.ROTATION_RANGE]);
                                // apply the rotation to the bone
                                go.transform.localRotation = new Quaternion(afValues[1], afValues[2], afValues[3], afValues[0]);
                            }
                            if (evalObj.m_kTransCPHandle != 65535)
                            {
                                // get the position values for the given time 't'
                                float[] afValues = new float[3];
                                float   offset   = evalObj.m_afCompScalars[(int)NiBSplineCompTransformEvaluator.COMP_.POSITION_OFFSET];
                                float   range    = evalObj.m_afCompScalars[(int)NiBSplineCompTransformEvaluator.COMP_.POSITION_RANGE];
                                splineObj.getCompactValueDegree3(t, afValues, 3, basisObj, evalObj.m_kTransCPHandle,
                                                                 offset,
                                                                 range);
                                go.transform.localPosition = new Vector3(afValues[0], afValues[1], afValues[2]);
                            }
                        }
                        //Debug.Log("drawLine", go);
                        Debug.DrawLine(go.transform.position, go.transform.parent.position);
                    }
                    else
                    {
                        Debug.LogWarning("Unknown animation type:" + evalObjA.GetType());
                    }
                }
            }
        }
Example #7
0
    static Material doMaterials(NIFFile nf, NiMesh mesh, GameObject go)
    {
        StringBuilder strB = new StringBuilder(20);

        if (standardShader == null)
        {
            standardShader = Shader.Find("Standard");
        }

        bool     IS_TERRAIN     = (nf.getStringTable().Contains("terrainL1"));
        bool     animated       = false;
        bool     presetMaterial = false;
        string   materialName   = null;
        Material mat            = null;


        Material mat2 = null;

        if (mesh.materialNames.Count > 0)
        {
            strB.Length = 0;
            strB.Append("materials/");
            strB.Append(mesh.materialNames[0]);
            mat2 = Resources.Load <Material>(strB.ToString());
            if (mat2 != null)
            {
                mat = Material.Instantiate <Material>(mat2);
            }
        }
        else
        {
            Debug.LogWarning("No mesh materials found in mesh :" + mesh.name);
        }

        if (mat == null)
        {
            // do materials/textures

            if (IS_TERRAIN)
            {
                materialName = "terrainmat";
            }

            if (mesh.materialNames.Contains("Ocean_Water_Shader") || mesh.materialNames.Contains("Flow_Water") || mesh.name.Contains("water_UP") || mesh.name.Contains("water_DOWN"))
            {
                materialName = "WaterMaterial";
            }

            bool alpha = (mesh.materialNames.Contains("TwoSided_Alpha_Specular") || mesh.materialNames.Contains("Lava_Flow_Decal"));
            foreach (string n in mesh.materialNames)
            {
                if (n.ToLower().Contains("alpha"))
                {
                    alpha = true;
                }
            }
            if (alpha)
            {
                materialName = "2sidedtransmat_fade";
            }

            // handle some simple animated "scrolling" textures
            animated = (mesh.materialNames.Contains("Additive_UVScroll_Distort") || mesh.materialNames.Contains("Lava_Flow_Decal") || mesh.materialNames.Contains("Local_Cloud_Flat") ||
                        mesh.materialNames.Contains("Alpha_UVScroll_Overlay_Foggy_Waterfall") || mesh.materialNames.Contains("Fat_spike12_m") || mesh.materialNames.Contains("pPlane1_m"));


            if (animated)
            {
                materialName = "2sidedtransmat_fade";
            }



            foreach (int eid in mesh.extraDataIDs)
            {
                NIFObject obj = nf.getObject(eid);
                if (obj is NiBooleanExtraData)
                {
                    NiBooleanExtraData fExtra = (NiBooleanExtraData)obj;
                    switch (fExtra.extraDataString)
                    {
                    case "doAlphaTest":
                        if (fExtra.booleanData)
                        {
                            materialName = "2sidedtransmat";
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            if (materialName == null)
            {
                if (standardMaterial == null)
                {
                    standardMaterial = new Material(standardShader);
                }
                mat          = Material.Instantiate(standardMaterial);
                materialName = standardMaterial.name;
            }
            else
            {
                mat = Material.Instantiate(Resources.Load <Material>(materialName));
            }
            //Debug.Log("Using guessed material[" + materialName + "] for " + mesh.name + " from list of materials: " + string.Join(",", mesh.materialNames.ToArray()), go);
        }
        else if (mat2 != null)
        {
            materialName   = mat2.name;
            presetMaterial = true;
            //Debug.Log("Using actual material[" + materialName + "] for " + mesh.name + " from list of materials: " + string.Join(",", mesh.materialNames.ToArray()), go);
        }
        else
        {
            Debug.LogWarning("No material found!?");
        }
#if UNITY_EDITOR
        MeshOriginalMaterial mom = go.AddComponent <MeshOriginalMaterial>();
        if (mesh.materialNames.Count > 0)
        {
            mom.materialName = mesh.materialNames[0];
        }
#endif

        if (presetMaterial)
        {
            foreach (int extraId in mesh.extraDataIDs)
            {
                NIFObject obj = nf.getObject(extraId);
                setMaterialProperty(mat, obj);
            }

            if (mat.HasProperty("doAlphaTest"))
            {
                if (mat.GetInt("doAlphaTest") == 0)
                {
                    strB.Length = 0;
                    strB.Append("materials/");
                    strB.Append(mat2.name);
                    strB.Append("_shader_opaque");

                    string shaderName = strB.ToString();
                    //Debug.Log("loading opaque shader:" + shaderName, go);
                    Shader shader = Resources.Load <Shader>(shaderName);
                    if (shader != null)
                    {
                        mat.shader = shader;
                    }
                }
            }
        }

        mat.enableInstancing = true;
        mat.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");



        if (animated)
        {
            NiFloatsExtraData extra = getFloatsExtraData(nf, mesh, "tex0ScrollRate");
            if (extra != null)
            {
                UVScroll scroller = go.AddComponent <UVScroll>();
                scroller.material = mat;

                scroller.xRate = extra.floatData[0];
                scroller.yRate = extra.floatData[1];
            }
        }

        foreach (int eid in mesh.extraDataIDs)
        {
            NIFObject obj = nf.getObject(eid);
            if (obj is NiFloatExtraData)
            {
                NiFloatExtraData fExtra = (NiFloatExtraData)obj;
                switch (fExtra.extraDataString)
                {
                case "scaleY":
                    if (mat.HasProperty("_MainTex"))
                    {
                        mat.mainTextureScale = new Vector2(mat.mainTextureScale.x, fExtra.floatData);
                    }
                    else
                    {
                        if (mat.HasProperty("scaleY"))
                        {
                            mat.SetFloat("scaleY", fExtra.floatData);
                        }
                        else
                        {
                            Debug.LogWarning("While trying to set scaleY, material[" + mat.name + "][" + materialName + "] doesn't have an appropriate texture property");
                        }
                    }
                    break;

                case "scale":
                    if (mat.HasProperty("_MainTex"))
                    {
                        mat.mainTextureScale = new Vector2(fExtra.floatData, mat.mainTextureScale.y);
                    }
                    else
                    {
                        if (mat.HasProperty("scale"))
                        {
                            mat.SetFloat("scale", fExtra.floatData);
                        }
                        else
                        {
                            Debug.LogWarning("While trying to set scale, material[" + mat.name + "][" + materialName + "] doesn't have an appropriate texture property");
                        }
                    }
                    break;

                default:
                    break;
                }
            }
        }

        string[] textureNameIds = getTextureIds(nf, mesh);

        if (presetMaterial)
        {
            foreach (int extraId in mesh.extraDataIDs)
            {
                NIFObject obj = nf.getObject(extraId);
                setMaterialProperty(mat, obj);
            }
        }

        if (mat.HasProperty("alphaTestRef"))
        {
            mat.SetFloat("alphaTestRef", 1.0f - mat.GetFloat("alphaTestRef"));
        }

        List <int> propIDs = mesh.nodePropertyIDs;
        foreach (int propID in propIDs)
        {
            NIFObject obj = nf.getObject(propID);

            if (obj is NiTexturingProperty)
            {
                NiTexturingProperty propObj = (NiTexturingProperty)obj;
                foreach (NifTexMap tex in propObj.texList)
                {
                    if (tex != null)
                    {
                        Debug.Log("\t" + tex.sourceTexLinkID);
                    }
                }

                int i = 0;
                foreach (NifTexMap tex in propObj.shaderMapList)
                {
                    string texName = "";
                    if (tex != null)
                    {
                        int sourceTexID = tex.sourceTexLinkID;
                        if (sourceTexID != -1)
                        {
                            NiSourceTexture sourceTex = (NiSourceTexture)nf.getObject(sourceTexID);
                            texName = sourceTex.texFilename;
                            if (presetMaterial)
                            {
                                strB.Length = 0;
                                if (IS_TERRAIN)
                                {
                                    strB.Append("_terrain");
                                    strB.Append(i);
                                }
                                else
                                {
                                    strB.Append("_");
                                    strB.Append(textureNameIds[i]);
                                }

                                // Debug.Log("attempt to set texture property :" + propertyName + " with texure:" + texName);

                                enqueSetTexture(mat, strB.ToString(), nf, texName);
                                //mat.SetTexture(propertyName, loadTexture(nf, texName));
                            }
                            else if (IS_TERRAIN)
                            {
                                strB.Length = 0;
                                strB.Append("_terrain");
                                strB.Append(i);
                                string param = strB.ToString();
                                //"_terrain" + i;
                                //Debug.Log("set " + param + " to " + texName + " mat:" + mat.name);
                                enqueSetTexture(mat, param, nf, texName);
                                //mat.SetTexture(param, loadTexture(nf, texName));
                            }
                            else
                            {
                                //Debug.Log("texName[" + texName + "]: id:" + textureNameIds[i]);
                                try
                                {
                                    switch (textureNameIds[i])
                                    {
                                    case "skyGradientTexture0":
                                    case "diffuseTexture":
                                    case "diffuseTextureXZ":
                                        enqueSetTexture(mat, "_MainTex", nf, texName);
                                        //mat.SetTexture("_MainTex", loadTexture(nf, texName));
                                        break;

                                    case "decalNormalTexture":
                                        enqueSetTexture(mat, "_DetailNormalMap", nf, texName);
                                        //mat.SetTexture("_DetailNormalMap", loadTexture(nf, texName));
                                        break;

                                    case "normalTexture":
                                        enqueSetTexture(mat, "_BumpMap", nf, texName);
                                        //mat.SetTexture("_BumpMap", loadTexture(nf, texName));
                                        break;

                                    case "glowTexture":
                                        mat.EnableKeyword("_EMISSION");
                                        if (mesh.materialNames.Contains("Lava_Flow_Decal"))
                                        {
                                            mat.SetColor("_EmissionColor", Color.red);
                                        }
                                        else
                                        {
                                            mat.SetColor("_EmissionColor", Color.white * 0.5f);
                                        }
                                        enqueSetTexture(mat, "_EmissionMap", nf, texName);
                                        //mat.SetTexture("_EmissionMap", loadTexture(nf, texName));
                                        break;

                                    case "glossTexture":
                                        enqueSetTexture(mat, "_MetallicGlossMap", nf, texName);
                                        //mat.SetTexture("_MetallicGlossMap", loadTexture(nf, texName));
                                        break;

                                    case "decalTexture":
                                    case "starMapTexture0":
                                        enqueSetTexture(mat, "_DetailAlbedoMap", nf, texName);
                                        //mat.SetTexture("_DetailAlbedoMap", loadTexture(nf, texName));
                                        break;

                                    default:
                                        //Debug.LogWarning("No shader material property for " + textureNameIds[i]);
                                        break;
                                    }
                                }catch (ArgumentOutOfRangeException ex)
                                {
                                    Debug.LogWarning("Texture id[" + i + "] was out of range of the texture name ids: " + textureNameIds.ToList());
                                    //mat.SetTexture("_MainTex", loadTexture(nf, texName));
                                    enqueSetTexture(mat, "_MainTex", nf, texName);
                                }
                            }
                        }
                    }
                    i++;
                }
            }
        }
        return(mat);
    }