//----------------------------------------------------------------------------- // Computes the static vertex lighting term from a large number of spherical samples //----------------------------------------------------------------------------- public bool ComputeVertexLightFromSpericalSamples(Vector3 pos, Vector3 normal, SourceProp prop, out Vector3 tempmem) { tempmem = Vector3.Zero; // Check to see if this vertex is in solid trace_t trace = ClipMap.Instance.Box_Trace(pos, pos, Vector3.Zero, Vector3.Zero, 0, 1); if (trace.allsolid || trace.startsolid) return false; int i; float t = 0.0f; // find any ambient lights worldlight_t skyLight = FindAmbientLight(); // sample world by casting N rays distributed across a sphere //float t = 0.0f; Vector3 upend = Vector3.Zero, color = Vector3.Zero; //int i; //for (i = 0; i < 2; i++) // 162 //{ // float flDot = Vector3.Dot(normal, s_randdir[i]); // if (flDot < 0.0f) // continue; // // FIXME: a good optimization would be to scale this per leaf // upend = ViewParams.VectorMA(pos, 56891, s_randdir[i]); // // Now that we've got a ray, see what surface we've hit // int surfid = R_LightVec(pos, upend, false, ref color); // if (surfid == -1) // continue; // // FIXME: Maybe make sure we aren't obstructed by static props? // // To do this, R_LightVec would need to return distance of hit... // // Or, we need another arg to R_LightVec to return black when hitting a static prop // ComputeAmbientFromSurface(surfid, skyLight, ref color); // t += flDot; // tempmem = ViewParams.VectorMA(tempmem, flDot, color); //} //if (t != 0.0f) // tempmem /= t; // Now deal with direct lighting bool hasSkylight = false; // Figure out the PVS info for this location int leaf = ClipMap.Instance.PointLeafnum(pos); bool[] pvs = ClipMap.Instance.ClusterPVS(ClipMap.Instance.LeafCluster(leaf)); Vector3 vecdirection = Vector3.Zero; // Now add in the direct lighting for (i = 0; i < world.worldlights.Length; i++) { worldlight_t wl = world.worldlights[i]; // FIXME: This is sort of a hack; only one skylight is allowed in the // lighting... if (wl.Type == EmitType.SKYLIGHT && hasSkylight) continue; if (wl.Cluster < 0 || pvs == null || !pvs[wl.Cluster]) continue; float flRatio = LightIntensityAndDirectionAtpoint(wl, pos, 4, ref vecdirection); // No light contribution? Get outta here! if (flRatio <= 0.0f) continue; // Check if we've got a skylight if (wl.Type == EmitType.SKYLIGHT) hasSkylight = true; // Figure out spotlight attenuation float flAngularRatio = WorldLightAngle(wl, wl.Normal, normal, vecdirection); // Add in the direct lighting tempmem = ViewParams.VectorMA(tempmem, flAngularRatio * flRatio, wl.Intensity); } return true; }
void ComputeModelVertexLighting(SourceProp prop, VTXModel mdl, Matrix matrix, List<Vector4> lightmem, List<Color3> colors) { // for each vertex //for (int i = 0; i < mdl.Lods[0].Meshes[0].StripGroups; ++i) { //ComputeVertexLightFromSpericalSamples //Vector3 pos = mdl.Meshes[0]. } }
void UpdateStaticPropLighting(SourceProp prop) { List<Color3> colors = new List<Color3>(); List<Vector4> lightmem = new List<Vector4>(); Matrix matrix = Matrix.AffineTransformation(1.0f, Vector3.Zero, Quaternion.RotationYawPitchRoll(prop.prop_t.Angles.X, -prop.prop_t.Angles.Z, prop.prop_t.Angles.Y), prop.prop_t.Origin); for (int bodyID = 0; bodyID < prop.srcModel.BodyParts.Count; bodyID++) { BodyPart bpart = prop.srcModel.BodyParts[bodyID]; for (int modelid = 0; modelid < bpart.VTXBodyPart.Models.Length; modelid++) { VTXModel mdl = bpart.VTXBodyPart.Models[modelid]; ComputeModelVertexLighting(prop, mdl, matrix, lightmem, colors); //for (int meshid = 0; meshid < mdl.Meshes.Count; meshid++) //{ // MDLMesh mesh = mdl.Meshes[meshid]; // // Add specular? //} } } }
static void LoadGameAndProps(BinaryReader br, Header header) { // Game Lump dgamelumpheader_t gameheader = new dgamelumpheader_t(); br.BaseStream.Seek(header.lumps[35].fileofs, SeekOrigin.Begin); int gamelen = header.lumps[35].filelen; gameheader.lumpCount = br.ReadInt32(); gameheader.gamelump = new dgamelump_t[gameheader.lumpCount]; for (int i = 0; i < gameheader.lumpCount; i++) { dgamelump_t game = new dgamelump_t(); game.id = br.ReadInt32(); game.flags = br.ReadUInt16(); game.version = br.ReadUInt16(); game.fileofs = br.ReadInt32(); game.filelen = br.ReadInt32(); gameheader.gamelump[i] = game; } // Read Static Props foreach (dgamelump_t game in gameheader.gamelump) { if (game.id == 1936749168) { // read prop dict StaticPropDictLump_t dict = new StaticPropDictLump_t(); br.BaseStream.Seek(game.fileofs, SeekOrigin.Begin); dict.dictEntries = br.ReadInt32(); dict.Name = new string[dict.dictEntries]; Dictionary<string, SourceModel> srcmodels = new Dictionary<string, SourceModel>(); for (int i = 0; i < dict.dictEntries; i++) { char[] name = br.ReadChars(128); dict.Name[i] = new string(name); // cut \0 chars int dindex = -1; if ((dindex = dict.Name[i].IndexOf('\0')) != -1) { dict.Name[i] = dict.Name[i].Substring(0, dindex); if (MDLReader.ReadFile(dict.Name[i])) { MDLReader.srcModel.Name = dict.Name[i]; srcmodels.Add(MDLReader.srcModel.Name, MDLReader.srcModel); } } } // Read prop leafs StaticPropLeafLump_t propleaf = new StaticPropLeafLump_t(); propleaf.leafEntries = br.ReadInt32(); propleaf.leaf = new ushort[propleaf.leafEntries]; for (int i = 0; i < propleaf.leafEntries; i++) { propleaf.leaf[i] = br.ReadUInt16(); } world.propleafs = propleaf; // read props int nStaticProps = br.ReadInt32(); StaticPropLump_t[] props = new StaticPropLump_t[nStaticProps]; for (int i = 0; i < nStaticProps; i++) { StaticPropLump_t prop = new StaticPropLump_t(); prop.Origin = SwapZY(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle())); prop.Angles = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); prop.PropType = br.ReadUInt16(); prop.PropName = dict.Name[(int)prop.PropType]; prop.FirstLeaf = br.ReadUInt16(); prop.LeafCount = br.ReadUInt16(); prop.Solid = br.ReadByte(); prop.Flags = br.ReadByte(); prop.Skin = br.ReadInt32(); prop.FadeMinDist = br.ReadSingle(); prop.FadeMaxDist = br.ReadSingle(); prop.LightingOrigin = SwapZY(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle())); if (game.version == 5) prop.ForcedFaceScale = br.ReadSingle(); else prop.ForcedFaceScale = 1f; props[i] = prop; SourceProp sprop = new SourceProp(prop); if (srcmodels.ContainsKey(prop.PropName)) { sprop.srcModel = srcmodels[prop.PropName]; world.sourceProps.Add(sprop); } // Index into leaves if (prop.LeafCount + prop.FirstLeaf < world.propleafs.leafEntries) { for (int j = 0; j < prop.LeafCount; j++) { ushort leafIndex = world.propleafs.leaf[prop.FirstLeaf + j]; if (leafIndex >= world.leafs.Length) { int test = 2; } world.leafs[leafIndex].staticProps.Add(sprop); } } } world.props = props; break; } } }