aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs397
1 files changed, 5 insertions, 392 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 7cce3b6..ebf5a06 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1113,7 +1113,7 @@ namespace OpenSim.Region.Framework.Scenes
1113 } 1113 }
1114 1114
1115 /// <summary> 1115 /// <summary>
1116 /// 1116 /// Create a terrain texture for this scene
1117 /// </summary> 1117 /// </summary>
1118 public void CreateTerrainTexture(bool temporary) 1118 public void CreateTerrainTexture(bool temporary)
1119 { 1119 {
@@ -1125,398 +1125,11 @@ namespace OpenSim.Region.Framework.Scenes
1125 return; 1125 return;
1126 1126
1127 if (terrain == null) 1127 if (terrain == null)
1128 { 1128 return;
1129 #region Fallback default maptile generation
1130
1131 int tc = Environment.TickCount;
1132 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain");
1133 Bitmap mapbmp = new Bitmap(256, 256);
1134 double[,] hm = Heightmap.GetDoubles();
1135 bool ShadowDebugContinue = true;
1136 //Color prim = Color.FromArgb(120, 120, 120);
1137 //Vector3 RayEnd = new Vector3(0, 0, 0);
1138 //Vector3 RayStart = new Vector3(0, 0, 0);
1139 //Vector3 direction = new Vector3(0, 0, -1);
1140 //Vector3 AXOrigin = new Vector3();
1141 //Vector3 AXdirection = new Vector3();
1142 //Ray testRay = new Ray();
1143 //EntityIntersection rt = new EntityIntersection();
1144 bool terraincorruptedwarningsaid = false;
1145
1146 float low = 255;
1147 float high = 0;
1148 for (int x = 0; x < 256; x++)
1149 {
1150 for (int y = 0; y < 256; y++)
1151 {
1152 float hmval = (float)hm[x, y];
1153 if (hmval < low)
1154 low = hmval;
1155 if (hmval > high)
1156 high = hmval;
1157 }
1158 }
1159
1160 float mid = (high + low) * 0.5f;
1161
1162 // temporary initializer
1163 float hfvalue = (float)m_regInfo.RegionSettings.WaterHeight;
1164 float hfvaluecompare = hfvalue;
1165 float hfdiff = hfvalue;
1166 int hfdiffi = 0;
1167
1168 for (int x = 0; x < 256; x++)
1169 {
1170 //int tc = System.Environment.TickCount;
1171 for (int y = 0; y < 256; y++)
1172 {
1173 //RayEnd = new Vector3(x, y, 0);
1174 //RayStart = new Vector3(x, y, 255);
1175
1176 //direction = Vector3.Norm(RayEnd - RayStart);
1177 //AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
1178 //AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
1179
1180 //testRay = new Ray(AXOrigin, AXdirection);
1181 //rt = m_sceneGraph.GetClosestIntersectingPrim(testRay);
1182
1183 //if (rt.HitTF)
1184 //{
1185 //mapbmp.SetPixel(x, y, prim);
1186 //}
1187 //else
1188 //{
1189 //float tmpval = (float)hm[x, y];
1190 float heightvalue = (float)hm[x, y];
1191
1192 if (heightvalue > (float)m_regInfo.RegionSettings.WaterHeight)
1193 {
1194 // scale height value
1195 heightvalue = low + mid * (heightvalue - low) / mid;
1196
1197 if (heightvalue > 255)
1198 heightvalue = 255;
1199
1200 if (heightvalue < 0)
1201 heightvalue = 0;
1202
1203 if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
1204 heightvalue = 0;
1205
1206 try
1207 {
1208 Color green = Color.FromArgb((int)heightvalue, 100, (int)heightvalue);
1209
1210 // Y flip the cordinates
1211 mapbmp.SetPixel(x, (256 - y) - 1, green);
1212
1213 //X
1214 // .
1215 //
1216 // Shade the terrain for shadows
1217 if ((x - 1 > 0) && (y - 1 > 0))
1218 {
1219 hfvalue = (float)hm[x, y];
1220 hfvaluecompare = (float)hm[x - 1, y - 1];
1221
1222 if (Single.IsInfinity(hfvalue) || Single.IsNaN(hfvalue))
1223 hfvalue = 0;
1224
1225 if (Single.IsInfinity(hfvaluecompare) || Single.IsNaN(hfvaluecompare))
1226 hfvaluecompare = 0;
1227
1228 hfdiff = hfvaluecompare - hfvalue;
1229
1230 if (hfdiff > 0.3f)
1231 {
1232
1233 }
1234 else if (hfdiff < -0.3f)
1235 {
1236 // We have to desaturate and blacken the land at the same time
1237 // we use floats, colors use bytes, so shrink are space down to
1238 // 0-255
1239
1240 try
1241 {
1242 hfdiffi = Math.Abs((int)((hfdiff * 4) + (hfdiff * 0.5))) + 1;
1243 if (hfdiff % 1 != 0)
1244 {
1245 hfdiffi = hfdiffi + Math.Abs((int)(((hfdiff % 1) * 0.5f) * 10f) - 1);
1246 }
1247 }
1248 catch (OverflowException)
1249 {
1250 m_log.Debug("[MAPTILE]: Shadow failed at value: " + hfdiff.ToString());
1251 ShadowDebugContinue = false;
1252 }
1253
1254 if (ShadowDebugContinue)
1255 {
1256 if ((256 - y) - 1 > 0)
1257 {
1258 Color Shade = mapbmp.GetPixel(x - 1, (256 - y) - 1);
1259
1260 int r = Shade.R;
1261
1262 int g = Shade.G;
1263 int b = Shade.B;
1264 Shade = Color.FromArgb((r - hfdiffi > 0) ? r - hfdiffi : 0, (g - hfdiffi > 0) ? g - hfdiffi : 0, (b - hfdiffi > 0) ? b - hfdiffi : 0);
1265 //Console.WriteLine("d:" + hfdiff.ToString() + ", i:" + hfdiffi + ", pos: " + x + "," + y + " - R:" + Shade.R.ToString() + ", G:" + Shade.G.ToString() + ", B:" + Shade.G.ToString());
1266 mapbmp.SetPixel(x - 1, (256 - y) - 1, Shade);
1267 }
1268 }
1269 }
1270 }
1271 }
1272 catch (ArgumentException)
1273 {
1274 if (!terraincorruptedwarningsaid)
1275 {
1276 m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", RegionInfo.RegionName);
1277 terraincorruptedwarningsaid = true;
1278 }
1279 Color black = Color.Black;
1280 mapbmp.SetPixel(x, (256 - y) - 1, black);
1281 }
1282 }
1283 else
1284 {
1285 // Y flip the cordinates
1286 heightvalue = (float)m_regInfo.RegionSettings.WaterHeight - heightvalue;
1287 if (heightvalue > 19)
1288 heightvalue = 19;
1289 if (heightvalue < 0)
1290 heightvalue = 0;
1291
1292 heightvalue = 100 - (heightvalue * 100) / 19;
1293
1294 if (heightvalue > 255)
1295 heightvalue = 255;
1296
1297 if (heightvalue < 0)
1298 heightvalue = 0;
1299
1300 if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
1301 heightvalue = 0;
1302
1303 try
1304 {
1305 Color water = Color.FromArgb((int)heightvalue, (int)heightvalue, 255);
1306 mapbmp.SetPixel(x, (256 - y) - 1, water);
1307 }
1308 catch (ArgumentException)
1309 {
1310 if (!terraincorruptedwarningsaid)
1311 {
1312 m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", RegionInfo.RegionName);
1313 terraincorruptedwarningsaid = true;
1314 }
1315 Color black = Color.Black;
1316 mapbmp.SetPixel(x, (256 - y) - 1, black);
1317 }
1318 }
1319 }
1320 //}
1321
1322 //tc = System.Environment.TickCount - tc;
1323 //m_log.Info("[MAPTILE]: Completed One row in " + tc + " ms");
1324 }
1325
1326 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms");
1327
1328 bool drawPrimVolume = true;
1329
1330 try
1331 {
1332 IConfig startupConfig = m_config.Configs["Startup"];
1333 drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", true);
1334 }
1335 catch
1336 {
1337 m_log.Warn("[MAPTILE]: Failed to load StartupConfig");
1338 }
1339
1340 if (drawPrimVolume)
1341 {
1342 tc = Environment.TickCount;
1343 m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile");
1344 List<EntityBase> objs = GetEntities();
1345
1346 lock (objs)
1347 {
1348 foreach (EntityBase obj in objs)
1349 {
1350 // Only draw the contents of SceneObjectGroup
1351 if (obj is SceneObjectGroup)
1352 {
1353 SceneObjectGroup mapdot = (SceneObjectGroup)obj;
1354 Color mapdotspot = Color.Gray; // Default color when prim color is white
1355 // Loop over prim in group
1356 foreach (SceneObjectPart part in mapdot.Children.Values)
1357 {
1358 if (part == null)
1359 continue;
1360
1361 // Draw if the object is at least 1 meter wide in any direction
1362 if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
1363 {
1364 // Try to get the RGBA of the default texture entry..
1365 //
1366 try
1367 {
1368 if (part == null)
1369 continue;
1370
1371 if (part.Shape == null)
1372 continue;
1373
1374 if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree)
1375 continue; // eliminates trees from this since we don't really have a good tree representation
1376 // if you want tree blocks on the map comment the above line and uncomment the below line
1377 //mapdotspot = Color.PaleGreen;
1378
1379 if (part.Shape.Textures == null)
1380 continue;
1381
1382 if (part.Shape.Textures.DefaultTexture == null)
1383 continue;
1384
1385 Color4 texcolor = part.Shape.Textures.DefaultTexture.RGBA;
1386
1387 // Not sure why some of these are null, oh well.
1388
1389 int colorr = 255 - (int)(texcolor.R * 255f);
1390 int colorg = 255 - (int)(texcolor.G * 255f);
1391 int colorb = 255 - (int)(texcolor.B * 255f);
1392
1393 if (!(colorr == 255 && colorg == 255 && colorb == 255))
1394 {
1395 //Try to set the map spot color
1396 try
1397 {
1398 // If the color gets goofy somehow, skip it *shakes fist at Color4
1399 mapdotspot = Color.FromArgb(colorr, colorg, colorb);
1400 }
1401 catch (ArgumentException)
1402 {
1403 }
1404 }
1405 }
1406 catch (IndexOutOfRangeException)
1407 {
1408 // Windows Array
1409 }
1410 catch (ArgumentOutOfRangeException)
1411 {
1412 // Mono Array
1413 }
1414
1415 Vector3 pos = part.GetWorldPosition();
1416
1417 // skip prim outside of retion
1418 if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
1419 continue;
1420
1421 // skip prim in non-finite position
1422 if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || Single.IsInfinity(pos.X)
1423 || Single.IsInfinity(pos.Y))
1424 continue;
1425
1426 // Figure out if object is under 256m above the height of the terrain
1427 bool isBelow256AboveTerrain = false;
1428
1429 try
1430 {
1431 isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
1432 }
1433 catch (Exception)
1434 {
1435 }
1436
1437 if (isBelow256AboveTerrain)
1438 {
1439 // Translate scale by rotation so scale is represented properly when object is rotated
1440 Vector3 scale = part.Shape.Scale;
1441 Quaternion rot = part.GetWorldRotation();
1442 scale *= rot;
1443
1444 // negative scales don't work in this situation
1445 scale.X = Math.Abs(scale.X);
1446 scale.Y = Math.Abs(scale.Y);
1447 scale.Z = Math.Abs(scale.Z);
1448
1449 // This scaling isn't very accurate and doesn't take into account the face rotation :P
1450 int mapdrawstartX = (int)(pos.X - scale.X);
1451 int mapdrawstartY = (int)(pos.Y - scale.Y);
1452 int mapdrawendX = (int)(pos.X + scale.X);
1453 int mapdrawendY = (int)(pos.Y + scale.Y);
1454
1455 // If object is beyond the edge of the map, don't draw it to avoid errors
1456 if (mapdrawstartX < 0 || mapdrawstartX > 255 || mapdrawendX < 0 || mapdrawendX > 255
1457 || mapdrawstartY < 0 || mapdrawstartY > 255 || mapdrawendY < 0
1458 || mapdrawendY > 255)
1459 continue;
1460
1461 int wy = 0;
1462
1463 bool breakYN = false; // If we run into an error drawing, break out of the
1464 // loop so we don't lag to death on error handling
1465 for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
1466 {
1467 for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
1468 {
1469 //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
1470 try
1471 {
1472 // Remember, flip the y!
1473 mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
1474 }
1475 catch (ArgumentException)
1476 {
1477 breakYN = true;
1478 }
1479
1480 if (breakYN)
1481 break;
1482 }
1483
1484 if (breakYN)
1485 break;
1486 }
1487 } // Object is within 256m Z of terrain
1488 } // object is at least a meter wide
1489 } // loop over group children
1490 } // entitybase is sceneobject group
1491 } // foreach loop over entities
1492 } // lock entities objs
1493
1494 m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms");
1495 } // end if drawPrimOnMaptle
1496
1497 byte[] data;
1498 try
1499 {
1500 data = OpenJPEG.EncodeFromImage(mapbmp, false);
1501 }
1502 catch (Exception)
1503 {
1504 return;
1505 }
1506
1507 LazySaveGeneratedMaptile(data,temporary);
1508 1129
1509 #endregion 1130 byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png");
1510 } 1131 if (data != null)
1511 else 1132 LazySaveGeneratedMaptile(data, temporary);
1512 {
1513 // Use the module to generate the maptile.
1514 byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png");
1515 if (data != null)
1516 {
1517 LazySaveGeneratedMaptile(data,temporary);
1518 }
1519 }
1520 } 1133 }
1521 1134
1522 public void LazySaveGeneratedMaptile(byte[] data, bool temporary) 1135 public void LazySaveGeneratedMaptile(byte[] data, bool temporary)