aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Materials
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Materials')
-rw-r--r--OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs281
1 files changed, 156 insertions, 125 deletions
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
index e95889d..6cde92e 100644
--- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
+++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
@@ -133,7 +133,7 @@ namespace OpenSim.Region.OptionalModules.Materials
133 IRequestHandler renderMaterialsPutHandler 133 IRequestHandler renderMaterialsPutHandler
134 = new RestStreamHandler("PUT", capsBase + "/", 134 = new RestStreamHandler("PUT", capsBase + "/",
135 (request, path, param, httpRequest, httpResponse) 135 (request, path, param, httpRequest, httpResponse)
136 => RenderMaterialsPostCap(request, agentID), 136 => RenderMaterialsPutCap(request, agentID),
137 "RenderMaterials", null); 137 "RenderMaterials", null);
138 MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); 138 MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler);
139 } 139 }
@@ -256,14 +256,19 @@ namespace OpenSim.Region.OptionalModules.Materials
256 { 256 {
257 if (m_regionMaterials.ContainsKey(id)) 257 if (m_regionMaterials.ContainsKey(id))
258 return; 258 return;
259 259
260 byte[] data = m_scene.AssetService.GetData(id.ToString()); 260
261 if (data == null) 261 // get all asset so it gets into cache
262 AssetBase matAsset = m_scene.AssetService.Get(id.ToString());
263
264// byte[] data = m_scene.AssetService.GetData(id.ToString());
265 if (matAsset == null || matAsset.Data == null || matAsset.Data.Length == 0 )
262 { 266 {
263 m_log.WarnFormat("[Materials]: Prim \"{0}\" ({1}) contains unknown material ID {2}", part.Name, part.UUID, id); 267 m_log.WarnFormat("[Materials]: Prim \"{0}\" ({1}) contains unknown material ID {2}", part.Name, part.UUID, id);
264 return; 268 return;
265 } 269 }
266 270
271 byte[] data = matAsset.Data;
267 OSDMap mat; 272 OSDMap mat;
268 try 273 try
269 { 274 {
@@ -284,6 +289,75 @@ namespace OpenSim.Region.OptionalModules.Materials
284 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); 289 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
285 OSDMap resp = new OSDMap(); 290 OSDMap resp = new OSDMap();
286 291
292 OSDArray respArr = new OSDArray();
293
294 if (req.ContainsKey("Zipped"))
295 {
296 OSD osd = null;
297
298 byte[] inBytes = req["Zipped"].AsBinary();
299
300 try
301 {
302 osd = ZDecompressBytesToOsd(inBytes);
303
304 if (osd != null && osd is OSDArray)
305 {
306 foreach (OSD elem in (OSDArray)osd)
307 {
308 try
309 {
310 UUID id = new UUID(elem.AsBinary(), 0);
311
312 lock (m_regionMaterials)
313 {
314 if (m_regionMaterials.ContainsKey(id))
315 {
316 OSDMap matMap = new OSDMap();
317 matMap["ID"] = OSD.FromBinary(id.GetBytes());
318 matMap["Material"] = m_regionMaterials[id];
319 respArr.Add(matMap);
320 }
321 else
322 {
323 m_log.Warn("[Materials]: request for unknown material ID: " + id.ToString());
324
325 // Theoretically we could try to load the material from the assets service,
326 // but that shouldn't be necessary because the viewer should only request
327 // materials that exist in a prim on the region, and all of these materials
328 // are already stored in m_regionMaterials.
329 }
330 }
331 }
332 catch (Exception e)
333 {
334 m_log.Error("Error getting materials in response to viewer request", e);
335 continue;
336 }
337 }
338 }
339 }
340 catch (Exception e)
341 {
342 m_log.Warn("[Materials]: exception decoding zipped CAP payload ", e);
343 //return "";
344 }
345 }
346
347 resp["Zipped"] = ZCompressOSD(respArr, false);
348 string response = OSDParser.SerializeLLSDXmlString(resp);
349
350 //m_log.Debug("[Materials]: cap request: " + request);
351 //m_log.Debug("[Materials]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary()));
352 //m_log.Debug("[Materials]: cap response: " + response);
353 return response;
354 }
355
356 public string RenderMaterialsPutCap(string request, UUID agentID)
357 {
358 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
359 OSDMap resp = new OSDMap();
360
287 OSDMap materialsFromViewer = null; 361 OSDMap materialsFromViewer = null;
288 362
289 OSDArray respArr = new OSDArray(); 363 OSDArray respArr = new OSDArray();
@@ -298,150 +372,108 @@ namespace OpenSim.Region.OptionalModules.Materials
298 { 372 {
299 osd = ZDecompressBytesToOsd(inBytes); 373 osd = ZDecompressBytesToOsd(inBytes);
300 374
301 if (osd != null) 375 if (osd != null && osd is OSDMap)
302 { 376 {
303 if (osd is OSDArray) // assume array of MaterialIDs designating requested material entries 377 materialsFromViewer = osd as OSDMap;
378
379 if (materialsFromViewer.ContainsKey("FullMaterialsPerFace"))
304 { 380 {
305 foreach (OSD elem in (OSDArray)osd) 381 OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"];
382 if (matsOsd is OSDArray)
306 { 383 {
384 OSDArray matsArr = matsOsd as OSDArray;
385
307 try 386 try
308 { 387 {
309 UUID id = new UUID(elem.AsBinary(), 0); 388 foreach (OSDMap matsMap in matsArr)
310
311 lock (m_regionMaterials)
312 { 389 {
313 if (m_regionMaterials.ContainsKey(id)) 390 uint primLocalID = 0;
391 try {
392 primLocalID = matsMap["ID"].AsUInteger();
393 }
394 catch (Exception e) {
395 m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message);
396 continue;
397 }
398
399 SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID);
400 if (sop == null)
314 { 401 {
315 OSDMap matMap = new OSDMap(); 402 m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString());
316 matMap["ID"] = OSD.FromBinary(id.GetBytes()); 403 continue;
317 matMap["Material"] = m_regionMaterials[id];
318 respArr.Add(matMap);
319 } 404 }
320 else 405
406 if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID))
321 { 407 {
322 m_log.Warn("[Materials]: request for unknown material ID: " + id.ToString()); 408 m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID);
409 continue;
410 }
323 411
324 // Theoretically we could try to load the material from the assets service, 412 OSDMap mat = null;
325 // but that shouldn't be necessary because the viewer should only request 413 try
326 // materials that exist in a prim on the region, and all of these materials 414 {
327 // are already stored in m_regionMaterials. 415 mat = matsMap["Material"] as OSDMap;
416 }
417 catch (Exception e)
418 {
419 m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message);
420 continue;
328 } 421 }
329 }
330 }
331 catch (Exception e)
332 {
333 m_log.Error("Error getting materials in response to viewer request", e);
334 continue;
335 }
336 }
337 }
338 else if (osd is OSDMap) // request to assign a material
339 {
340 materialsFromViewer = osd as OSDMap;
341 422
342 if (materialsFromViewer.ContainsKey("FullMaterialsPerFace")) 423 Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length);
343 { 424 if (te == null)
344 OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"]; 425 {
345 if (matsOsd is OSDArray) 426 m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID);
346 { 427 continue;
347 OSDArray matsArr = matsOsd as OSDArray; 428 }
348 429
349 try 430 UUID id;
350 { 431 if (mat == null)
351 foreach (OSDMap matsMap in matsArr) 432 {
433 // This happens then the user removes a material from a prim
434 id = UUID.Zero;
435 }
436 else
437 {
438 id = StoreMaterialAsAsset(agentID, mat, sop);
439 }
440
441 int face = -1;
442
443 if (matsMap.ContainsKey("Face"))
444 {
445 face = matsMap["Face"].AsInteger();
446 Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face);
447 faceEntry.MaterialID = id;
448 }
449 else
352 { 450 {
353 uint primLocalID = 0; 451 if (te.DefaultTexture == null)
354 try { 452 m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID);
355 primLocalID = matsMap["ID"].AsUInteger();
356 }
357 catch (Exception e) {
358 m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message);
359 continue;
360 }
361
362 OSDMap mat = null;
363 try
364 {
365 mat = matsMap["Material"] as OSDMap;
366 }
367 catch (Exception e)
368 {
369 m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message);
370 continue;
371 }
372
373 SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID);
374 if (sop == null)
375 {
376 m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString());
377 continue;
378 }
379
380 if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID))
381 {
382 m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID);
383 continue;
384 }
385
386 Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length);
387 if (te == null)
388 {
389 m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID);
390 continue;
391 }
392
393
394 UUID id;
395 if (mat == null)
396 {
397 // This happens then the user removes a material from a prim
398 id = UUID.Zero;
399 }
400 else 453 else
401 { 454 te.DefaultTexture.MaterialID = id;
402 id = StoreMaterialAsAsset(agentID, mat, sop); 455 }
403 }
404 456
457 //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id);
405 458
406 int face = -1; 459 // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually
460 sop.Shape.TextureEntry = te.GetBytes();
407 461
408 if (matsMap.ContainsKey("Face")) 462 if (sop.ParentGroup != null)
409 { 463 {
410 face = matsMap["Face"].AsInteger(); 464 sop.TriggerScriptChangedEvent(Changed.TEXTURE);
411 Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face); 465 sop.ParentGroup.HasGroupChanged = true;
412 faceEntry.MaterialID = id; 466 sop.ScheduleFullUpdate();
413 }
414 else
415 {
416 if (te.DefaultTexture == null)
417 m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID);
418 else
419 te.DefaultTexture.MaterialID = id;
420 }
421
422 //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id);
423
424 // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually
425 sop.Shape.TextureEntry = te.GetBytes();
426
427 if (sop.ParentGroup != null)
428 {
429 sop.TriggerScriptChangedEvent(Changed.TEXTURE);
430 sop.UpdateFlag = UpdateRequired.FULL;
431 sop.ParentGroup.HasGroupChanged = true;
432 sop.ScheduleFullUpdate();
433 }
434 } 467 }
435 } 468 }
436 catch (Exception e) 469 }
437 { 470 catch (Exception e)
438 m_log.Warn("[Materials]: exception processing received material ", e); 471 {
439 } 472 m_log.Warn("[Materials]: exception processing received material ", e);
440 } 473 }
441 } 474 }
442 } 475 }
443 } 476 }
444
445 } 477 }
446 catch (Exception e) 478 catch (Exception e)
447 { 479 {
@@ -449,7 +481,6 @@ namespace OpenSim.Region.OptionalModules.Materials
449 //return ""; 481 //return "";
450 } 482 }
451 } 483 }
452
453 484
454 resp["Zipped"] = ZCompressOSD(respArr, false); 485 resp["Zipped"] = ZCompressOSD(respArr, false);
455 string response = OSDParser.SerializeLLSDXmlString(resp); 486 string response = OSDParser.SerializeLLSDXmlString(resp);