diff options
author | UbitUmarov | 2016-09-04 04:19:10 +0100 |
---|---|---|
committer | UbitUmarov | 2016-09-04 04:19:10 +0100 |
commit | 6526de04cbbc48b91d77f9c99f033eaca2bfa78c (patch) | |
tree | d42eda453db818061f3dc9c4762aca3b709cfcb3 /OpenSim/Region | |
parent | tests making sure evering thing is coerently wrong.. (diff) | |
download | opensim-SC-6526de04cbbc48b91d77f9c99f033eaca2bfa78c.zip opensim-SC-6526de04cbbc48b91d77f9c99f033eaca2bfa78c.tar.gz opensim-SC-6526de04cbbc48b91d77f9c99f033eaca2bfa78c.tar.bz2 opensim-SC-6526de04cbbc48b91d77f9c99f033eaca2bfa78c.tar.xz |
make sure materials are cached. Split POST and PUT handlers for better readability
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs | 281 |
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); |