Add a bunch of conversion files from BasilOS.

Add THIRDPARTYLICENSE and licenses from many a source.
Add DLLs for Promise library.
This commit is contained in:
Robert Adams
2017-06-14 22:04:59 -07:00
parent 31f6eab8a8
commit 88d609cc0b
27 changed files with 5477 additions and 21 deletions
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+22
View File
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 Real Serious Games
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+7
View File
@@ -0,0 +1,7 @@
Copyright 2011-2016 Cesium Contributors
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+26
View File
@@ -0,0 +1,26 @@
LookingGlass: http://lookingglassviewer.org
https://github.com/Misterblue/LookingGlass-Viewer
/* Copyright (c) Robert Adams
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of the copyright holder may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// November 30, 2008
+25
View File
@@ -0,0 +1,25 @@
Copyright (c) Contributors, http://opensimulator.org/
See CONTRIBUTORS.TXT for a full list of copyright holders.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the OpenSimulator Project nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+47
View File
@@ -0,0 +1,47 @@
The parameter parsing and some logging code was derived from the
DSGToolKit (https://github.com/intelvwi/DSGToolkit.git) which was
published with the following license:
/* -----------------------------------------------------------------
* Copyright (c) 2013 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of the Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
* YOUR JURISDICTION. It is licensee's responsibility to comply with any
* export regulations applicable in licensee's jurisdiction. Under
* CURRENT (May 2000) U.S. export regulations this software is eligible
* for export from the U.S. and can be downloaded by or otherwise
* exported or reexported worldwide EXCEPT to U.S. embargoed destinations
* which include Cuba, Iraq, Libya, North Korea, Iran, Syria, Sudan,
* Afghanistan and any other country to which the U.S. has embargoed
* goods and services.
* -----------------------------------------------------------------
*/
+69
View File
@@ -0,0 +1,69 @@
Radegast Metaverse Client
Copyright (c) 2009-2014, Radegast Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the application "Radegast", nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Based on SLeek (BSD License)
Copyright © 2006-2008, Paul Clement (a.k.a. Delta)
All rights reserved.
Uses PrimMesher (BSD License)
© 2010 Dahlia Trimble
http://forge.opensimulator.org/gf/project/primmesher/
Uses AIMLBot (LGPL License)
The AIMLBot library (Program#) is a .NET implementation of the AIML standard.
© 2006 Nicholas H.Tollervey (http://ntoll.org)
http://aimlbot.sourceforge.net/
Uses FMOD Library (FMOD Non Commercial License)
FMOD Ex SoundSystem Copyright © 2005-2009 Firelight Technologies Pty, Ltd.
Redistributions in binary form must follow the following rules:
* The FMOD library cannot be used for resale or other commercial distribution
* This license cannot be used for products which do not make profit but are still commercially released
* This license cannot be used for commercial services, where the executable containing fmod is not sold, but the data is
(If you want to redistribute Radegast commercially, remove fmodex.dll, fmodex*.so and fmodex*.dylib)
Uses Ogg Vorbis codec (BSD License)
Copyright © 2002, Xiph.org Foundation
Uses log4net (Apache 2.0 License)
Copyright © Apache Software Foundation
Uses LSL parser from OpenSimulator project (BSD License)
Copyright © Contributors, http://opensimulator.org/
Uses OpenTK library (MIT License)
Copyright © 2006 - 2009 The Open Toolkit library.
http://www.opentk.com/
Uses artwork files are licenced under the
Creative Commons Share and Share Alike 3.0
Copyright © 2002-2009 Linden Research Inc.
Command Line Library (MIT License)
Copyright © 2005 - 2010 Giacomo Stelluti Scala
http://commandline.codeplex.com/
+24
View File
@@ -0,0 +1,24 @@
Copyright (c) 2006-2016, openmetaverse.co
All rights reserved.
- Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Neither the name of the openmetaverse.co nor the names
of its contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
+232
View File
@@ -0,0 +1,232 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using log4net;
using RSG;
using OMV = OpenMetaverse;
using OMVS = OpenMetaverse.StructuredData;
using OMVA = OpenMetaverse.Assets;
using OMVR = OpenMetaverse.Rendering;
namespace org.herbal3d.convoar {
// Convert entitygroup items -- simpification and mergings
public class BConverter {
private static string _logHeader = "BConverter";
private GlobalContext _context;
// Lists of similar faces indexed by the texture hash
public class SimilarFaces : Dictionary<BHash, List<FaceInfo>> {
public SimilarFaces() : base() {
}
public void AddSimilarFace(BHash pHash, FaceInfo pFace) {
if (!this.ContainsKey(pHash)) {
this.Add(pHash, new List<FaceInfo>());
}
this[pHash].Add(pFace);
}
}
public BConverter(GlobalContext context) {
_context = context;
}
// Loop through all the shared faces (faces that share the same material) and create
// one mesh for all the faces. This entails selecting one of the faces to be the
// root face and then displacing all the vertices, rotations, ... to be based
// from that root face.
// We find the root face by looking for one "in the middle"ish so as to keep the offset
// math as small as possible.
// This creates reorgScene.rebuildFaceEntities from reorgScene.similarFaces.
public EntityGroupList ConvertEntitiesIntoSharedMaterialMeshes(EntityGroupList staticEntities) {
// Go through all the static items and make a list of all the meshes with similar textures
SimilarFaces similarFaces = new SimilarFaces();
staticEntities.ForEachExtendedPrim(ep => {
ep.faces.ForEach(faceInfo => {
OMV.Primitive.TextureEntryFace tef = faceInfo.textureEntry;
BHash hashCode = new BHashULong(tef.GetHashCode());
similarFaces.AddSimilarFace(hashCode, faceInfo);
});
});
EntityGroupList rebuilt = new EntityGroupList(
similarFaces.Values.Select(similarFaceList => {
ExtendedPrim ep = CreateExtendedPrimFromSimilarFaces(similarFaceList);
// The created ExtendedPrim needs to be packaged into an EntityGroup
EntityGroup eg = new EntityGroup();
eg.Add(new ExtendedPrimGroup(ep));
return eg;
}).ToList()
);
return rebuilt;
}
// Check all the faces in an EntityGroup (usually a single SL entity) and
// merge faces using the same material into single meshes.
// This reduces large linksets into smaller sets of meshes and also merges
// similar prim faces into single meshes.
public EntityGroupList ConvertEntityGroupIntoSharedMaterialMeshes(EntityGroup eg) {
// Go through all the materialed meshes and see if there are meshes to share
SimilarFaces similarFaces = new SimilarFaces();
// int totalFaces = 0; // DEBUG DEBUG
eg.ForEach(epg => {
ExtendedPrim ep = epg.primaryExtendePrim;
ep.faces.ForEach(faceInfo => {
OMV.Primitive.TextureEntryFace tef = faceInfo.textureEntry;
BHash hashCode = new BHashULong(tef.GetHashCode());
similarFaces.AddSimilarFace(hashCode, faceInfo);
// totalFaces++; // DEBUG DEBUG
});
});
/*
EntityGroup rebuilt = new EntityGroup(
similarFaces.Values.Select(similarFaceList => {
ExtendedPrim ep = CreateExtendedPrimFromSimilarFaces(similarFaceList);
_context.log.DebugFormat("{0} ConvertEntityGroupIntoSharedMaterialMeshes: create ExtendedPrim: {1}",
_logHeader, ep.Stats());
return new ExtendedPrimGroup(ep);
}).ToList()
);
*/
EntityGroupList rebuilt = new EntityGroupList(
similarFaces.Values.Select(similarFaceList => {
ExtendedPrim ep = CreateExtendedPrimFromSimilarFaces(similarFaceList);
// The created ExtendedPrim needs to be packaged into an EntityGroup
EntityGroup newEg = new EntityGroup();
newEg.Add(new ExtendedPrimGroup(ep));
return newEg;
}).ToList()
);
return rebuilt;
}
// Given a list of faces, merge the meshes into a single mesh.
// THese faces could be from different prims so position computation has to go
// to the face's containing prim and then relocated to its new root.
// The returned ExtendedPrim has a location in the world and all the mesh vertices
// have been moved and oriented to that new location.
private ExtendedPrim CreateExtendedPrimFromSimilarFaces(List<FaceInfo> similarFaceList) {
// Loop through the faces and find the root. If this is faces from a single linkset, this
// will find the root prim as the reference. Otherwise it will just find some root
// prim.
// There might be a need to find the 'middle' prim of a cluster if position jitter
// becomes a problem.
FaceInfo rootFace = null;
foreach (FaceInfo faceInfo in similarFaceList) {
if (faceInfo.containingPrim != null && faceInfo.containingPrim.isRoot) {
rootFace = faceInfo;
// _context.log.DebugFormat("{0} CreateExtendedPrimFromSimilarFaces: one similar is root.", _logHeader);
break;
}
}
if (rootFace == null) {
// If there wasn't a root entity in the list, just pick a random one
rootFace = similarFaceList.First();
// _context.log.DebugFormat("{0} CreateExtendedPrimFromSimilarFaces: no root. Assuming first face", _logHeader);
}
ExtendedPrim rootEp = rootFace.containingPrim;
// Create the new combined object
ExtendedPrim newEp = new ExtendedPrim(rootEp);
newEp.ID = OMV.UUID.Random();
newEp.coordSystem = rootEp.coordSystem.clone();
newEp.isRoot = true;
newEp.positionIsParentRelative = false;
// The merged mesh is located at the root's location with no rotation
if (rootEp.fromOS.SOP != null) {
newEp.translation = rootEp.fromOS.SOP.GetWorldPosition();
}
else {
_context.log.LogDebug("{0} CreateExtendedPrimFromSimilarFaces: no OS link. Assuming translation of zero", _logHeader);
newEp.translation = OMV.Vector3.Zero;
}
newEp.rotation = OMV.Quaternion.Identity;
newEp.scale = rootEp.scale;
// The 'new ExtendedPrim' above copied the faceted mesh faces. We're doing it over so undo that.
newEp.faces.Clear();
FaceInfo newFace = new FaceInfo(999, rootEp);
newFace.textureEntry = rootFace.textureEntry;
newFace.textureID = rootFace.textureID;
newFace.faceImage = rootFace.faceImage;
newFace.hasAlpha = rootFace.hasAlpha;
newEp.faces.Add(newFace);
// _context.log.DebugFormat("{0} CreateExtendedPrimFromSimilarFaces: newEp.trans={1}, newEp.rot={2}",
// _logHeader, newEp.translation, newEp.rotation);
// Based of the root face, create a new mesh that holds all the faces
similarFaceList.ForEach(faceInfo => {
// _context.log.DebugFormat("{0} CreateExtendedPrimFromSimilarFaces: adding face {1} from {2}, verts={3}, ind={4}",
// _logHeader, faceInfo.num, faceInfo.containingPrim.ID,
// faceInfo.vertexs.Count, faceInfo.indices.Count);
// 'faceInfo' and 'ep' is the vertex/indices we're adding to 'newFace'
ExtendedPrim ep = faceInfo.containingPrim;
// The indices of the mesh being added needs to be advanced 'indicesBase' since the vertices are
// added to the end of the existing list.
int indicesBase = newFace.vertexs.Count;
// Translate all the new vertices to world coordinates then subtract the 'newEp' location.
// All rotation is removed to make computation simplier
OMV.Vector3 worldPos = OMV.Vector3.Zero;
OMV.Quaternion worldRot = OMV.Quaternion.Identity;
if (ep.fromOS.SOP != null) {
worldPos = ep.fromOS.SOP.GetWorldPosition();
worldRot = ep.fromOS.SOP.GetWorldRotation();
}
// _context.log.DebugFormat("{0} CreateExtendedPrimFromSimilarFaces: map {1}, wPos={2}, wRot={3}",
// _logHeader, faceInfo.containingPrim.ID, worldPos, worldRot);
newFace.vertexs.AddRange(faceInfo.vertexs.Select(vert => {
OMVR.Vertex newVert = new OMVR.Vertex();
var worldLocationOfVertex = vert.Position * worldRot + worldPos;
newVert.Position = worldLocationOfVertex - newEp.translation;
newVert.Normal = vert.Normal * worldRot;
newVert.TexCoord = vert.TexCoord;
return newVert;
}));
newFace.indices.AddRange(faceInfo.indices.Select(ind => (ushort)(ind + indicesBase)));
});
// _context.log.DebugFormat("{0} CreateExtendedPrimFromSimilarFaces: COMPLETE: verts={1}. ind={2}",
// _logHeader, newFace.vertexs.Count, newFace.indices.Count);
return newEp;
}
}
}
+158
View File
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using log4net;
using RSG;
using OMV = OpenMetaverse;
using OMVS = OpenMetaverse.StructuredData;
using OMVA = OpenMetaverse.Assets;
using OMVR = OpenMetaverse.Rendering;
namespace org.herbal3d.convoar {
// Convert things from OpenSimulator to EntityGroup things
public class BConverterOS {
private static string _logHeader = "BConverterOS";
private IAssetFetcher _assetFetcher;
private PrimToMesh _mesher;
private GlobalContext _context;
// Lists of similar faces indexed by the texture hash
public class SimilarFaces : Dictionary<BHash, List<FaceInfo>> {
public SimilarFaces() : base() {
}
public void AddSimilarFace(BHash pHash, FaceInfo pFace) {
if (! this.ContainsKey(pHash)) {
this.Add(pHash, new List<FaceInfo>());
}
this[pHash].Add(pFace);
}
}
public BConverterOS(IAssetFetcher assetFetcher, PrimToMesh mesher, GlobalContext context) {
_assetFetcher = assetFetcher;
_mesher = mesher;
_context = context;
}
// Convert a SceneObjectGroup into an EntityGroup
public IPromise<EntityGroup> Convert(SceneObjectGroup sog, IAssetFetcher assetFetcher) {
var prom = new Promise<EntityGroup>();
// Create meshes for all the parts of the SOG
Promise<ExtendedPrimGroup>.All(
sog.Parts.Select(sop => {
OMV.Primitive aPrim = sop.Shape.ToOmvPrimitive();
return _mesher.CreateMeshResource(sog, sop, aPrim, _assetFetcher, OMVR.DetailLevel.Highest, _context.stats);
} )
)
// Tweak the converted parts individually (scale, texturize, ...)
.Then(epgs => {
return epgs.Select(epg => {
// If scaling is done in the mesh, do it now
if (!_context.parms.DisplayTimeScaling) {
PrimToMesh.ScaleMeshes(epg);
foreach (ExtendedPrim ep in epg.Values) {
ep.scale = new OMV.Vector3(1, 1, 1);
}
}
// The prims in the group need to be decorated with texture/image information
UpdateTextureInfo(epg, assetFetcher);
return epg;
});
})
.Catch(e => {
_context.log.LogError("{0} Failed meshing of SOG. ID={1}: {2}", _logHeader, sog.UUID, e);
prom.Reject(new Exception(String.Format("failed meshing of SOG. ID={0}: {1}", sog.UUID, e)));
})
.Done (epgs => {
prom.Resolve(new EntityGroup(epgs.ToList()));
}) ;
return prom;
}
// Convert a SceneObjectPart into an ExtendedPrimGroup
public IPromise<ExtendedPrimGroup> Convert(SceneObjectGroup sog, SceneObjectPart sop) {
return null;
}
/// <summary>
/// Scan through all the ExtendedPrims and finish any texture updating.
/// This includes UV coordinate mappings and fetching any image that goes with the texture.
/// </summary>
/// <param name="epGroup">Collections of meshes to update</param>
/// <param name="assetFetcher">Fetcher for getting images, etc</param>
/// <param name="pMesher"></param>
private void UpdateTextureInfo(ExtendedPrimGroup epGroup, IAssetFetcher assetFetcher) {
ExtendedPrim ep = epGroup.primaryExtendePrim;
foreach (FaceInfo faceInfo in ep.faces) {
// While we're in the neighborhood, map the texture coords based on the prim information
_mesher.UpdateCoords(faceInfo, ep.fromOS.primitive);
UpdateFaceInfoWithTexture(faceInfo, assetFetcher);
}
}
// Check to see if the FaceInfo has a textureID and, if so, read it in and populate the FaceInfo
// with that texture data.
public void UpdateFaceInfoWithTexture(FaceInfo faceInfo, IAssetFetcher assetFetcher) {
// If the texture includes an image, read it in.
OMV.UUID texID = faceInfo.textureEntry.TextureID;
try {
faceInfo.hasAlpha = (faceInfo.textureEntry.RGBA.A != 1.0f);
if (texID != OMV.UUID.Zero && texID != OMV.Primitive.TextureEntry.WHITE_TEXTURE) {
faceInfo.textureID = texID;
faceInfo.persist = new BasilPersist(Gltf.MakeAssetURITypeImage, texID.ToString(), _context);
faceInfo.persist.GetUniqueTextureData(faceInfo, assetFetcher)
.Catch(e => {
// Could not get the texture. Print error and otherwise blank out the texture
faceInfo.textureID = null;
faceInfo.faceImage = null;
_context.log.LogError("{0} UpdateTextureInfo. {1}", _logHeader, e);
})
.Then(imgInfo => {
faceInfo.faceImage = imgInfo.image;
faceInfo.hasAlpha |= imgInfo.hasTransprency;
});
}
}
catch (Exception e) {
_context.log.LogError("{0}: UpdateFaceInfoWithTexture: exception updating faceInfo. id={1}: {2}",
_logHeader, texID, e);
}
}
}
}
+379
View File
@@ -0,0 +1,379 @@
/*
* Copyright (c) 2016 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace org.herbal3d.convoar {
// Basil wrapper for hash functions.
// There are several different hashing systems ranging from int's to SHA versions.
// The model here is to create a hasher of the desired type, do Add's of things to
// hash, and complete with a Finish() to return a BHash that contains the hash value.
// Since some hash functions are incremental (doing Add's) while some are buffer
// oriented (create a hash of a byte buffer), the interface is built to cover both.
// Some optimizations are implemented internally (like not copying the buffer
// for buffer based hashers if Finish(bytes) is used).
//
// var hasher = new BHashSHA256();
// BHash bHash = hasher.Finish(buffer);
// byte[] theHash = bHash.ToByte();
//
// Note that BHash has IEquatable and IComparible so it can be used in Dictionaries
// and sorted Lists.
//
// The C# GetHashCode() method returns an int that is usually based on location.
// Signatures should really be at least 64 bits so these routines generate
// ulong's for hashes and fold them to make the int for GetHashCode().
// Create a BHasher, do a bunch of 'Add's, then Finish().
public interface IBHasher {
// Create a new object implementing BHasher, then Add values to be hashed
void Add(byte c);
void Add(ushort c);
void Add(uint c);
void Add(ulong c);
void Add(float c);
void Add(byte[] c);
BHash Finish();
// Finish and add byte array.
// If no Add's before, can do the hashing without copying the byte array
BHash Finish(byte[] c);
BHash Finish(byte[] c, int offset, int len);
BHash Hash();
}
// ======================================================================
// BHasher computes a BHash which holds the hash value after Finish() is called.
public abstract class BHash : IEquatable<BHash>, IComparable<BHash> {
public abstract override string ToString();
public abstract byte[] ToBytes();
public abstract ulong ToULong(); // returns the hash of the hash if not int based hash
public abstract bool Equals(BHash other);
public abstract int CompareTo(BHash obj);
// public abstract int Compare(BHash x, BHash y);
public abstract override int GetHashCode();
}
// A hash that is an Int32
public class BHashULong : BHash {
private ulong _hash;
public BHashULong() {
_hash = 0;
}
public BHashULong(ulong initialHash) {
_hash = initialHash;
}
// the .NET GetHashCode uses an int. Make conversion easy.
public BHashULong(int initialHash) {
_hash = (ulong)initialHash;
}
public override string ToString() {
return _hash.ToString();
}
public override byte[] ToBytes() {
return BitConverter.GetBytes(_hash);
}
public override ulong ToULong() {
return _hash;
}
public override bool Equals(BHash other) {
bool ret = false;
if (other != null) {
BHash bh = other as BHashULong;
if (bh != null) {
ret = _hash.Equals(bh.ToULong());
}
}
return ret;
}
public override int CompareTo(BHash other) {
int ret = 1;
if (other != null) {
BHashULong bh = other as BHashULong;
if (bh != null) {
ret = _hash.CompareTo(bh.ToULong());
}
}
return ret;
}
public override int GetHashCode() {
ulong upper = (_hash >> 32 )& 0xffffffff;
ulong lower = _hash & 0xffffffff;
return (int)(upper ^ lower);
}
}
// A hash that is an array of bytes
public class BHashBytes : BHash {
private byte[] _hash;
public BHashBytes() {
_hash = new byte[0];
}
public BHashBytes(byte[] initialHash) {
_hash = initialHash;
}
public override string ToString() {
// code found in FSAssetService -- is removing hyphen the right thing to do?
// return BitConverter.ToString(hash).Replace("-", String.Empty);
// Decided to leave removing the hyphen to the caller -- depends on what they
// are using the string for.
return BitConverter.ToString(_hash);
}
public override byte[] ToBytes() {
return _hash;
}
public override ulong ToULong() {
return this.MakeHashCode();
}
public override bool Equals(BHash other) {
bool ret = false;
if (other != null) {
BHash bh = other as BHashBytes;
if (bh != null) {
ret = _hash.Equals(bh.ToBytes());
}
}
return ret;
}
public override int CompareTo(BHash other) {
int ret = 1;
if (other != null) {
BHash bh = other as BHashBytes;
if (bh != null) {
byte[] otherb = bh.ToBytes();
if (_hash.Length != otherb.Length) {
ret = _hash.Length.CompareTo(otherb.Length);
}
else {
ret = 0; // start off assuming they are equal
for (int ii = 0; ii < _hash.Length; ii++) {
ret = _hash[ii].CompareTo(otherb[ii]);
if (ret != 0) break;
}
}
}
}
return ret;
}
public override int GetHashCode()
{
ulong hashhash = this.MakeHashCode();
ulong upper = (hashhash >> 32 )& 0xffffffff;
ulong lower = hashhash & 0xffffffff;
return (int)(upper ^ lower);
}
public ulong MakeHashCode() {
ulong h = 5381;
for (int ii = 0; ii < _hash.Length; ii++) {
h = ((h << 5) + h) + (ulong)(_hash[ii]);
}
return h;
}
}
// ======================================================================
// ======================================================================
public abstract class BHasher
{
public BHasher() {
}
}
// A hasher that builds up a buffer of bytes ('building') and then hashes over same
public abstract class BHasherBytes : BHasher, IBHasher {
protected byte[] building;
protected int buildingLoc;
protected int allocStep = 1024;
public BHasherBytes() : base() {
building = new byte[allocStep];
buildingLoc = 0;
}
public void Add(byte c) {
byte[] bytes = BitConverter.GetBytes(c);
AddBytes(bytes, 0, bytes.Length);
}
public void Add(ushort c) {
byte[] bytes = BitConverter.GetBytes(c);
AddBytes(bytes, 0, bytes.Length);
}
public void Add(uint c) {
byte[] bytes = BitConverter.GetBytes(c);
AddBytes(bytes, 0, bytes.Length);
}
public void Add(ulong c) {
byte[] bytes = BitConverter.GetBytes(c);
AddBytes(bytes, 0, bytes.Length);
}
public void Add(float c) {
byte[] bytes = BitConverter.GetBytes(c);
AddBytes(bytes, 0, bytes.Length);
}
public void Add(byte[] c) {
AddBytes(c, 0, c.Length);
}
// Implemented by derived class
public abstract BHash Finish();
// Helper function for simple byte array
public virtual BHash Finish(byte[] c) {
return this.Finish(c, 0, c.Length);
}
// Implemented by derived class
public abstract BHash Finish(byte[] c, int offset, int len);
// Implemented by derived class
public abstract BHash Hash();
// Add the given number of bytes to the byte array being built
protected void AddBytes(byte[] addition, int offset, int len) {
if (offset + len > addition.Length) {
throw new ArgumentException(String.Format("BHasherBytes.AddBytes: addition parameters off end of array. addition.len={0}, offset={1}, len={2}",
addition.Length, offset, len));
}
if (len > 0) {
if (buildingLoc + len > building.Length) {
// New data requires expanding the data buffer
byte[] newBuilding = new byte[buildingLoc + len + allocStep];
Buffer.BlockCopy(building, 0, newBuilding, 0, buildingLoc);
building = newBuilding;
}
Buffer.BlockCopy(addition, offset, building, buildingLoc, len);
buildingLoc += len;
}
}
}
// ======================================================================
// ULong hash code taken from Meshmerizer
public class BHasherMdjb2 : BHasherBytes, IBHasher {
BHashULong hash = new BHashULong();
public BHasherMdjb2() : base() {
}
public override BHash Finish() {
hash = new BHashULong(ComputeMdjb2Hash(building, 0, buildingLoc));
return hash;
}
public override BHash Finish(byte[] c, int offset, int len) {
if (building.Length > 0) {
AddBytes(c, offset, len);
hash = new BHashULong(ComputeMdjb2Hash(building, 0, buildingLoc));
}
else {
// if no 'Add's were done, don't copy the input data
hash = new BHashULong(ComputeMdjb2Hash(c, offset, len));
}
return hash;
}
private ulong ComputeMdjb2Hash(byte[] c, int offset, int len) {
ulong h = 5381;
for (int ii = offset; ii < offset+len; ii++) {
h = ((h << 5) + h) + (ulong)(c[ii]);
}
return h;
}
public override BHash Hash() {
return hash;
}
}
// ======================================================================
public class BHasherMD5 : BHasherBytes, IBHasher {
BHashBytes hash = new BHashBytes();
public BHasherMD5() : base() {
}
public override BHash Finish() {
MD5 md5 = MD5.Create();
hash = new BHashBytes(md5.ComputeHash(building, 0, buildingLoc));
return hash;
}
public override BHash Finish(byte[] c) {
return this.Finish(c, 0, c.Length);
}
public override BHash Finish(byte[] c, int offset, int len) {
MD5 md5 = MD5.Create();
if (building.Length > 0) {
AddBytes(c, offset, len);
hash = new BHashBytes(md5.ComputeHash(building, 0, buildingLoc));
}
else {
// if no 'Add's were done, don't copy the input data
hash = new BHashBytes(md5.ComputeHash(c, offset, len));
}
return hash;
}
public override BHash Hash() {
return hash;
}
}
// ======================================================================
public class BHasherSHA256 : BHasherBytes, IBHasher {
BHashBytes hash = new BHashBytes();
public BHasherSHA256() : base() {
}
public override BHash Finish() {
using (SHA256CryptoServiceProvider SHA256 = new SHA256CryptoServiceProvider()) {
hash = new BHashBytes(SHA256.ComputeHash(building, 0, buildingLoc));
}
return hash;
}
public override BHash Finish(byte[] c, int offset, int len) {
using (SHA256CryptoServiceProvider SHA256 = new SHA256CryptoServiceProvider()) {
if (building.Length > 0) {
AddBytes(c, offset, len);
hash = new BHashBytes(SHA256.ComputeHash(building, 0, buildingLoc));
}
else {
// if no 'Add's were done, don't copy the input data
hash = new BHashBytes(SHA256.ComputeHash(c, offset, len));
}
}
return hash;
}
public override BHash Hash() {
return hash;
}
}
}
+156
View File
@@ -0,0 +1,156 @@
/*
* Copyright (c) 2016 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Drawing;
using log4net;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using RSG;
using OMV = OpenMetaverse;
using OMVA = OpenMetaverse.Assets;
using OpenMetaverse.Imaging;
namespace org.herbal3d.convoar {
// A Promise based interface to the asset fetcher
public abstract class IAssetFetcher : IDisposable {
public abstract IPromise<OMVA.AssetTexture> FetchTexture(EntityHandle handle);
public abstract IPromise<Image> FetchTextureAsImage(EntityHandle handle);
public abstract IPromise<byte[]> FetchRawAsset(EntityHandle handle);
public abstract void Dispose();
}
// Fetch an asset from the OpenSimulator asset system
public class OSAssetFetcher : IAssetFetcher {
private ILog m_log;
private string LogHeader = "[OSAssetFetcher]";
private Scene m_scene;
private ConvoarParams m_params;
public OSAssetFetcher(Scene scene, ILog logger, ConvoarParams pParams) {
m_scene = scene;
m_log = logger;
m_params = pParams;
}
public override IPromise<byte[]> FetchRawAsset(EntityHandle handle) {
var prom = new Promise<byte[]>();
// Don't bother with async -- this call will hang until the asset is fetched
byte[] returnBytes = m_scene.AssetService.GetData(handle.GetOSAssetString());
if (returnBytes.Length > 0) {
prom.Resolve(returnBytes);
}
else {
prom.Reject(new Exception("FetchRawAsset: could not fetch asset " + handle.ToString()));
}
return prom;
}
/// <summary>
/// Fetch a texture and return an OMVA.AssetTexture. The only information initialized
/// in the AssetTexture is the UUID and the binary data.s
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public override IPromise<OMVA.AssetTexture> FetchTexture(EntityHandle handle) {
var prom = new Promise<OMVA.AssetTexture>();
// Don't bother with async -- this call will hang until the asset is fetched
AssetBase asset = m_scene.AssetService.Get(handle.GetOSAssetString());
if (asset.IsBinaryAsset && asset.Type == (sbyte)OMV.AssetType.Texture) {
OMVA.AssetTexture tex = new OMVA.AssetTexture(handle.GetUUID(), asset.Data);
try {
if (tex.Decode()) {
prom.Resolve(tex);
}
else {
prom.Reject(new Exception("FetchTexture: could not decode JPEG2000 texture. ID=" + handle.ToString()));
}
}
catch (Exception e) {
prom.Reject(new Exception("FetchTexture: exception decoding JPEG2000 texture. ID=" + handle.ToString()
+ ", e=" + e.ToString()));
}
}
else {
prom.Reject(new Exception("FetchTexture: asset was not of type texture. ID=" + handle.ToString()));
}
return prom;
}
/// <summary>
/// Fetch a texture and return an OMVA.AssetTexture. The only information initialized
/// in the AssetTexture is the UUID and the binary data.
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public override IPromise<Image> FetchTextureAsImage(EntityHandle handle) {
var prom = new Promise<Image>();
// Don't bother with async -- this call will hang until the asset is fetched
AssetBase asset = m_scene.AssetService.Get(handle.GetOSAssetString());
if (asset != null) {
if (asset.IsBinaryAsset && asset.Type == (sbyte)OMV.AssetType.Texture) {
try {
Image imageDecoded = null;
if (m_params.UseOpenSimImageDecoder) {
IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
imageDecoded = imgDecoder.DecodeToImage(asset.Data);
}
else {
ManagedImage mimage;
if (OpenJPEG.DecodeToImage(asset.Data, out mimage, out imageDecoded)) {
mimage = null;
}
else {
imageDecoded = null;
}
}
prom.Resolve(imageDecoded);
}
catch (Exception e) {
prom.Reject(new Exception("FetchTextureAsImage: exception decoding JPEG2000 texture. ID=" + handle.ToString()
+ ", e=" + e.ToString()));
}
}
else {
prom.Reject(new Exception("FetchTextureAsImage: asset was not of type texture. ID=" + handle.ToString()));
}
}
else {
prom.Reject(new Exception("FetchTextureAsImage: could not fetch texture asset. ID=" + handle.ToString()));
}
return prom;
}
public override void Dispose() {
m_scene = null;
}
}
class BasilAssetss {
}
}
+279
View File
@@ -0,0 +1,279 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using RSG;
using log4net;
using OMV = OpenMetaverse;
namespace org.herbal3d.convoar {
// Classes to handle persistance of output.
// The converted images go somewhere for later fetching.
// These classes wrap the logic for storing the binary, images, and json files
// for later processing.
public class BasilPersist {
private string _assetType;
private string _assetInfo;
private GlobalContext _context;
private static string _logHeader = "BasilPersist";
// Texture cache used when processing one region
private static Dictionary<int, ImageInfo> textureCache = new Dictionary<int, ImageInfo>();
public class ImageInfo {
public bool hasTransprency;
public Image image;
public ImageInfo() {
hasTransprency = false;
}
public ImageInfo(Image pImage) {
hasTransprency = false;
image = pImage;
}
// Check the image in this TextureInfo for transparency and set this.hasTransparency.
public bool CheckForTransparency() {
hasTransprency = false;
if (image != null) {
if (Image.IsAlphaPixelFormat(image.PixelFormat)) {
// The image could have alpha values in it
Bitmap bitmapImage = image as Bitmap;
if (bitmapImage != null) {
for (int xx = 0; xx < bitmapImage.Width; xx++) {
for (int yy = 0; yy < bitmapImage.Height; yy++) {
if (bitmapImage.GetPixel(xx, yy).A != 255) {
hasTransprency = true;
break;
}
}
}
}
}
}
return hasTransprency;
}
}
public BasilPersist(string pAssetType, string pInfo, GlobalContext pContext) {
_assetType = pAssetType;
_assetInfo = pInfo;
_context = pContext;
}
public void WriteImage(Image image) {
string texFilename = CreateFilename();
if (!File.Exists(texFilename)) {
Image texImage = ConstrainTextureSize(image);
try {
/*
using (Bitmap textureBitmap = new Bitmap(texImage.Width, texImage.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb)) {
// convert the raw image into a channeled image
using (Graphics graphics = Graphics.FromImage(textureBitmap)) {
graphics.DrawImage(texImage, 0, 0);
graphics.Flush();
}
// Write out the converted image as PNG
textureBitmap.Save(texFilename, System.Drawing.Imaging.ImageFormat.Png);
}
*/
// _context.log.DebugFormat("{0} WriteOutImageForEP: id={1}, hasAlpha={2}, format={3}",
// _logHeader, faceInfo.textureID, faceInfo.hasAlpha, texImage.PixelFormat);
texImage.Save(texFilename, ImageFormat.Png);
}
catch (Exception e) {
_context.log.LogError("{0} FAILED PNG FILE CREATION: {0}", e);
}
}
}
// Keep a cache if image data and either fetch and Image or return a cached instance.
public Promise<ImageInfo> GetUniqueTextureData(FaceInfo faceInfo, IAssetFetcher assetFetcher) {
string imageFilename = CreateFilename();
Promise<ImageInfo> prom = new Promise<ImageInfo>();
EntityHandle textureHandle = new EntityHandle((OMV.UUID)faceInfo.textureID);
int hash = textureHandle.GetHashCode();
if (textureCache.ContainsKey(hash)) {
// _context.log.DebugFormat("{0} GetUniqueTextureData. found image in cache. {1}", _logHeader, faceInfo.textureID);
prom.Resolve(textureCache[hash]);
}
else {
// If the converted file already exists, read that one in
if (File.Exists(imageFilename)) {
var anImage = Image.FromFile(imageFilename);
// _context.log.DebugFormat("{0} GetUniqueTextureData: reading in existing image from {1}", _logHeader, imageFilename);
ImageInfo imgInfo = new ImageInfo(anImage);
imgInfo.CheckForTransparency();
textureCache.Add(hash, imgInfo);
prom.Resolve(imgInfo);
}
else {
// If not in the cache or converted file, get it from the asset server
// _context.log.DebugFormat("{0} GetUniqueTextureData. not in file or cache. Fetching image. {1}", _logHeader, faceInfo.textureID);
assetFetcher.FetchTextureAsImage(textureHandle)
.Catch(e => {
prom.Reject(new Exception(String.Format("Could not fetch texture. handle={0}. e={1}", textureHandle, e)));
})
.Then(theImage => {
try {
// _context.log.DebugFormat("{0} GetUniqueTextureData. adding to cache. {1}", _logHeader, faceInfo.textureID);
ImageInfo imgInfo = new ImageInfo(theImage);
imgInfo.CheckForTransparency();
textureCache.Add(textureHandle.GetHashCode(), imgInfo);
// _context.log.DebugFormat("{0} GetUniqueTextureData. handle={1}, hash={2}, caching", _logHeader, textureHandle, hash);
prom.Resolve(imgInfo);
}
catch (Exception e) {
prom.Reject(new Exception(String.Format("Texture conversion failed. handle={0}. e={1}", textureHandle, e)));
}
});
}
}
return prom;
}
public string CreateFilename() {
return CreateFilename(_assetType, _assetInfo);
}
public string CreateFilename(string assetType, string assetInfo) {
string fname = "";
string targetDir = ResolveAndCreateDir(_context.parms.GltfTargetDir);
if (targetDir != null) {
if (assetType == Gltf.MakeAssetURITypeImage) {
fname = JoinFilePieces(targetDir, assetInfo + ".png");
}
if (assetType == Gltf.MakeAssetURITypeBuff) {
fname = JoinFilePieces(targetDir, _context.contextName + "_" + assetInfo + ".bin");
}
if (assetType == Gltf.MakeAssetURITypeMesh) {
fname = JoinFilePieces(targetDir, assetInfo + ".mesh");
}
}
return fname;
}
public string CreateURI() {
return CreateURI(_assetType, _assetInfo);
}
public string CreateURI(string assetType, string assetInfo) {
string uuri = "";
string targetDir = ResolveAndCreateDir(_context.parms.GltfTargetDir);
if (targetDir != null) {
if (assetType == Gltf.MakeAssetURITypeImage) {
uuri = _context.parms.URIBase + assetInfo + ".png";
}
if (assetType == Gltf.MakeAssetURITypeBuff) {
uuri = _context.parms.URIBase + _context.contextName + "_" + assetInfo + ".bin";
}
if (assetType == Gltf.MakeAssetURITypeMesh) {
uuri = _context.parms.URIBase + assetInfo + ".mesh";
}
}
return uuri;
}
// If the image is larger than a max, resize the image.
// Not sure why, but transparency is lost in this conversion.
private Image ConstrainTextureSize(Image inImage) {
int size = _context.parms.MaxTextureSize;
if (inImage.Width > size || inImage.Height > size) {
int sizeW = size;
int sizeH = size;
/*
if (inImage.Width > size) {
sizeH = (int)(inImage.Height * (size / inImage.Width));
}
else {
sizeW = (int)(inImage.Width * (size / inImage.Height));
}
*/
Image thumbNail = new Bitmap(sizeW, sizeH, inImage.PixelFormat);
using (Graphics g = Graphics.FromImage(thumbNail)) {
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle rect = new Rectangle(0, 0, sizeW, sizeH);
g.DrawImage(inImage, rect);
}
return thumbNail;
}
return inImage;
}
/// <summary>
/// Turn the passed relative path name into an absolute directory path and
/// create the directory if it does not exist.
/// </summary>
/// <param name="pDir">Absolute or relative path to a directory</param>
/// <returns>Absolute path to directory or 'null' if cannot resolve or create the directory</returns>
public static string ResolveAndCreateDir(string pDir) {
string absDir = null;
try {
absDir = Path.GetFullPath(pDir);
if (!Directory.Exists(absDir)) {
Directory.CreateDirectory(absDir);
}
}
catch (Exception e) {
// _context.log.ErrorFormat("{0} Failed creation of GLTF file directory. dir={1}, e: {2}",
// _logHeader, absDir, e);
return null;
}
return absDir;
}
/// <summary>
/// Combine two filename pieces so there is one directory separator between.
/// This replaces System.IO.Path.Combine which has the nasty feature that it
/// ignores the first string if the second begins with a separator.
/// It assumes that it's root and you don't want to join. Wish they had asked me.
/// </summary>
/// <param name="first"></param>
/// <param name="last"></param>
/// <returns></returns>
public static string JoinFilePieces(string first, string last) {
string separator = "" + Path.DirectorySeparatorChar;
// string separator = "/"; // both .NET and mono are happy with forward slash
string f = first;
string l = last;
while (f.EndsWith(separator)) f = f.Substring(f.Length - 1);
while (l.StartsWith(separator)) l = l.Substring(1, l.Length - 1);
return f + separator + l;
}
}
}
+243
View File
@@ -0,0 +1,243 @@
/*
* Copyright (c) 2016 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Text;
using log4net;
using OpenSim.Region.CoreModules.World.LegacyMap;
using OMV = OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OMVS = OpenMetaverse.StructuredData;
using OMVA = OpenMetaverse.Assets;
using OMVR = OpenMetaverse.Rendering;
namespace org.herbal3d.convoar {
public class BasilTerrain {
private static string LogHeader = "BasilTerrain";
// Create a mesh for the terrain of the current scene
public static EntityGroup CreateTerrainMesh(GlobalContext context,
Scene scene,
PrimToMesh assetMesher, IAssetFetcher assetFetcher) {
ITerrainChannel terrainDef = scene.Heightmap;
int XSize = terrainDef.Width;
int YSize = terrainDef.Height;
float[,] heightMap = new float[XSize, YSize];
if (context.parms.HalfRezTerrain) {
context.log.LogDebug("{0}: CreateTerrainMesh. creating half sized terrain sized <{1},{2}>", LogHeader, XSize/2, YSize/2);
// Half resolution mesh that approximates the heightmap
heightMap = new float[XSize/2, YSize/2];
for (int xx = 0; xx < XSize; xx += 2) {
for (int yy = 0; yy < YSize; yy += 2) {
float here = terrainDef.GetHeightAtXYZ(xx+0, yy+0, 26);
float ln = terrainDef.GetHeightAtXYZ(xx+1, yy+0, 26);
float ll = terrainDef.GetHeightAtXYZ(xx+0, yy+1, 26);
float lr = terrainDef.GetHeightAtXYZ(xx+1, yy+1, 26);
heightMap[xx/2, yy/2] = (here + ln + ll + lr) / 4;
}
}
}
else {
context.log.LogDebug("{0}: CreateTerrainMesh. creating terrain sized <{1},{2}>", LogHeader, XSize/2, YSize/2);
for (int xx = 0; xx < XSize; xx++) {
for (int yy = 0; yy < YSize; yy++) {
heightMap[xx, yy] = terrainDef.GetHeightAtXYZ(xx, yy, 26);
}
}
}
context.log.LogDebug("{0}: CreateTerrainMesh. calling MeshFromHeightMap", LogHeader);
ExtendedPrimGroup epg = assetMesher.MeshFromHeightMap(heightMap,
terrainDef.Width, terrainDef.Height);
// Number found in RegionSettings.cs as DEFAULT_TERRAIN_TEXTURE_3
OMV.UUID defaultTextureID = new OMV.UUID("179cdabd-398a-9b6b-1391-4dc333ba321f");
OMV.Primitive.TextureEntry te = new OMV.Primitive.TextureEntry(defaultTextureID);
if (context.parms.CreateTerrainSplat) {
// Use the OpenSim maptile generator to create a texture for the terrain
var terrainRenderer = new TexturedMapTileRenderer();
terrainRenderer.Initialise(scene, null); // doesn't use config param
var mapbmp = new Bitmap(terrainDef.Width, terrainDef.Height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
terrainRenderer.TerrainToBitmap(mapbmp);
// The built terrain mesh will have one face in the mesh
OMVR.Face aFace = epg.primaryExtendePrim.fromOS.facetedMesh.Faces.First();
FaceInfo fi = new FaceInfo(0, epg.primaryExtendePrim, aFace, te.CreateFace(0));
fi.textureID = OMV.UUID.Random();
fi.faceImage = mapbmp;
fi.hasAlpha = false;
fi.persist = new BasilPersist(Gltf.MakeAssetURITypeImage, fi.textureID.ToString(), context);
epg.primaryExtendePrim.faces.Add(fi);
}
else {
// Fabricate a texture
// The built terrain mesh will have one face in the mesh
OMVR.Face aFace = epg.primaryExtendePrim.fromOS.facetedMesh.Faces.First();
FaceInfo fi = new FaceInfo(0, epg.primaryExtendePrim, aFace, te.CreateFace(0));
fi.textureID = defaultTextureID;
assetFetcher.FetchTextureAsImage(new EntityHandle(defaultTextureID))
.Catch(e => {
context.log.LogError("{0} CreateTerrainMesh: unable to fetch default terrain texture: id={1}: {2}",
LogHeader, defaultTextureID, e);
})
.Then(theImage => {
// This will happen later so hopefully soon enough for anyone using the image
fi.faceImage = theImage;
});
fi.hasAlpha = false;
epg.primaryExtendePrim.faces.Add(fi);
}
EntityGroup eg = new EntityGroup();
eg.Add(epg);
return eg;
}
// A structure to hold vertex information that also includes the index for building indices.
private struct Vert : IEquatable<Vert>{
public OMV.Vector3 Position;
public OMV.Vector3 Normal;
public OMV.Vector2 TexCoord;
public uint index;
// Methods so this will work in a Dictionary
public override int GetHashCode() {
int hash = Position.GetHashCode();
hash = hash * 31 + Normal.GetHashCode();
hash = hash * 31 + TexCoord.GetHashCode();
return hash;
}
public bool Equals(Vert other) {
return Position == other.Position
&& Normal == other.Normal
&& TexCoord == other.TexCoord;
}
}
// PrimMesher has a terrain mesh generator but it doesn't compute normals.
// TODO: Optimize by removing vertices that are just mid points.
// Having a vertex for every height is very inefficient especially for flat areas.
public static OMVR.Face TerrainMesh(float[,] heights, float realSizeX, float realSizeY, ILog log) {
List<ushort> indices = new List<ushort>();
int sizeX = heights.GetLength(0);
int sizeY = heights.GetLength(1);
// build the vertices in an array for computing normals and eventually for
// optimizations.
Vert[,] vertices = new Vert[sizeX, sizeY];
float stepX = (realSizeX+1f) / (float)sizeX; // the real dimension step for each heightmap step
float stepY = (realSizeY+1f) / (float)sizeY;
float coordStepX = 1.0f / (float)sizeX; // the coordinate dimension step for each heightmap step
float coordStepY = 1.0f / (float)sizeY;
uint index = 0;
for (int xx = 0; xx < sizeX; xx++) {
for (int yy = 0; yy < sizeY; yy++) {
Vert vert = new Vert();
vert.Position = new OMV.Vector3(stepX * xx, stepY * yy, heights[xx, yy]);
vert.Normal = new OMV.Vector3(0f, 1f, 0f); // normal pointing up for the moment
vert.TexCoord = new OMV.Vector2(coordStepX * xx, coordStepY * yy);
vert.index = index++;
vertices[xx, yy] = vert;
}
}
// Compute the normals
// Take three corners of each quad and calculate the normal for the vector
// a--b--e--...
// | | |
// d--c--h--...
// The triangle a-b-d calculates the normal for a, etc
for (int xx = 0; xx < sizeX-1; xx++) {
for (int yy = 0; yy < sizeY-1; yy++) {
vertices[xx,yy].Normal = MakeNormal(vertices[xx, yy], vertices[xx + 1, yy], vertices[xx, yy + 1]);
}
}
// The vertices along the edges need an extra pass to compute the normals
for (int xx = 0; xx < sizeX-1 ; xx++) {
vertices[xx, sizeY - 1].Normal = MakeNormal(vertices[xx, sizeY - 1], vertices[xx + 1, sizeY - 1], vertices[xx, sizeY - 2]);
}
for (int yy = 0; yy < sizeY - 1; yy++) {
vertices[sizeX -1, yy].Normal = MakeNormal(vertices[sizeX -1 , yy], vertices[sizeX - 1, yy + 1], vertices[sizeX - 2, yy]);
}
vertices[sizeX -1, sizeY - 1].Normal = MakeNormal(vertices[sizeX -1 , sizeY - 1], vertices[sizeX - 2, sizeY - 1], vertices[sizeX - 1, sizeY - 2]);
// Convert our vertices into the format expected by the caller
List<OMVR.Vertex> vertexList = new List<OMVR.Vertex>();
for (int xx = 0; xx < sizeX; xx++) {
for (int yy = 0; yy < sizeY; yy++) {
Vert vert = vertices[xx, yy];
OMVR.Vertex oVert = new OMVR.Vertex();
oVert.Position = vert.Position;
oVert.Normal = vert.Normal;
oVert.TexCoord = vert.TexCoord;
vertexList.Add(oVert);
}
}
// Make indices for all the vertices.
// Pass over the matrix and create two triangles for each quad
//
// 00-----01
// | f1 /|
// | / |
// | / f2 |
// 10-----11
//
// Counter Clockwise
for (int xx = 0; xx < sizeX - 1; xx++) {
for (int yy = 0; yy < sizeY - 1; yy++) {
indices.Add((ushort)vertices[xx + 0, yy + 0].index);
indices.Add((ushort)vertices[xx + 1, yy + 0].index);
indices.Add((ushort)vertices[xx + 0, yy + 1].index);
indices.Add((ushort)vertices[xx + 0, yy + 1].index);
indices.Add((ushort)vertices[xx + 1, yy + 0].index);
indices.Add((ushort)vertices[xx + 1, yy + 1].index);
}
}
OMVR.Face aface = new OMVR.Face();
aface.Vertices = vertexList;
aface.Indices = indices;
return aface;
}
// Given a root (aa) and two adjacent vertices (bb, cc), computer the normal for aa
private static OMV.Vector3 MakeNormal(Vert aa, Vert bb, Vert cc) {
OMV.Vector3 mm = aa.Position - bb.Position;
OMV.Vector3 nn = aa.Position - cc.Position;
OMV.Vector3 theNormal = OMV.Vector3.Cross(mm, nn);
theNormal.Normalize();
return theNormal;
}
}
}
+67 -13
View File
@@ -29,11 +29,34 @@ using OpenSim.Region.CoreModules.World.Terrain;
using OpenSim.Region.CoreModules.World.Archiver;
using OpenSim.Tests.Common;
using OpenSim.Data.Null;
using OpenSim.Region.PhysicsModule.BasicPhysics;
using OpenSim.Region.PhysicsModules.SharedBase;
using Nini.Config;
using log4net;
using OMV = OpenMetaverse;
namespace org.herbal3d.convoar {
// Class passed around for global context for this region module instance.
// NOT FOR PASSING DATA! Only used for global resources like logging, configuration
// parameters, statistics, and the such.
public class GlobalContext {
public ConvoarParams parms;
public BasilStats stats;
public Logger log;
public string contextName; // a unique identifier for this context -- used in filenames, ...
public GlobalContext(ConvoarParams pParms, Logger pLog)
{
parms = pParms;
log = pLog;
stats = null;
contextName = String.Empty;
}
}
class ConvOAR {
Dictionary<string, string> _parameters;
@@ -44,6 +67,8 @@ namespace org.herbal3d.convoar {
string _optDisplacement;
string _optRotation;
GlobalContext _context;
private string Invocation() {
return @"Invocation:
convoar
@@ -63,6 +88,10 @@ convoar
}
public void Start(string[] args) {
_context = new GlobalContext(new ConvoarParams(), new Logger());
_context.parms.MergeCommandLine(args);
_parameters = ParameterParse.ParseArguments(args, /*firstOpFlag*/ false, /*multipleFiles*/ false);
foreach (KeyValuePair<string, string> kvp in _parameters) {
switch (kvp.Key) {
@@ -76,33 +105,35 @@ convoar
_optRotation = kvp.Value;
break;
case "--verbose":
Logger.Verbose = true;
_context.log.Verbose = true;
break;
case ParameterParse.LAST_PARAM:
_inputOAR = kvp.Value;
break;
case ParameterParse.ERROR_PARAM:
// this means the parser found something it didn't like
Logger.LogError("Parameter error: " + kvp.Value);
Logger.LogError(Invocation());
_context.log.LogError("Parameter error: " + kvp.Value);
_context.log.LogError(Invocation());
return;
default:
Logger.LogError("ERROR: Unknown Parameter: " + kvp.Key);
Logger.LogError(Invocation());
return;
if (! _context.parms.SetParameterValue(kvp.Key, kvp.Value)) {
_context.log.LogError("ERROR: Unknown Parameter: " + kvp.Key);
_context.log.LogError(Invocation());
return;
}
break;
}
}
// Validate parameters
if (String.IsNullOrEmpty(_inputOAR)) {
Logger.LogError("An input OAR file must be specified");
Logger.LogError(Invocation());
_context.log.LogError("An input OAR file must be specified");
_context.log.LogError(Invocation());
return;
}
if (String.IsNullOrEmpty(_outputDir)) {
_outputDir = "./out";
Logger.LogDebug("Output directory defaulting to {0}", _outputDir);
_context.log.LogDebug("Output directory defaulting to {0}", _outputDir);
}
@@ -136,6 +167,14 @@ convoar
IRegionSerialiserModule serializerModule = new SerialiserModule();
scene.RegisterModuleInterface<IRegionSerialiserModule>(serializerModule);
IUserAccountService userAccountService = new NullUserAccountService();
scene.RegisterModuleInterface<IUserAccountService>(userAccountService);
PhysicsScene physScene = CreateSimplePhysicsEngine();
((INonSharedRegionModule)physScene).AddRegion(scene);
((INonSharedRegionModule)physScene).RegionLoaded(scene);
scene.PhysicsScene = physScene;
scene.LandChannel = new TestLandChannel(scene); // simple land with no parcels
var terrainModule = new TerrainModule();
terrainModule.AddRegion(scene);
@@ -144,12 +183,27 @@ convoar
// Load the archive into our scene
ArchiveReadRequest archive = new ArchiveReadRequest(scene, _inputOAR, Guid.Empty, options);
archive.DearchiveRegion();
archive.DearchiveRegion(false);
// Convert SOGs from OAR into EntityGroups
Logger.Log("Num assets = {0}", memAssetService.NumAssets);
Logger.Log("Num SOGs = {0}", scene.GetSceneObjectGroups().Count);
_context.log.Log("Num assets = {0}", memAssetService.NumAssets);
_context.log.Log("Num SOGs = {0}", scene.GetSceneObjectGroups().Count);
// Convert all the loaded SOGs and images into meshes and our format
}
private PhysicsScene CreateSimplePhysicsEngine() {
IConfigSource config = new IniConfigSource();
config.AddConfig("Startup");
config.Configs["Startup"].Set("physics", "basicphysics");
PhysicsScene pScene = new BasicScene();
INonSharedRegionModule mod = pScene as INonSharedRegionModule;
mod.Initialise(config);
return pScene;
}
}
}
+362
View File
@@ -0,0 +1,362 @@
/*
* Copyright (c) 2016 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Some code covered by: Copyright (c) Contributors, http://opensimulator.org/
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace org.herbal3d.convoar {
public class ConvoarParams {
private static string _logHeader = "[CONVOAR PARAMS]";
public ConvoarParams() {
SetParameterDefaultValues();
}
#pragma warning disable CS0649 // disable 'never assigned' warnings
public bool Enabled; // True if, well, enabled.
public string AssetDirectory; // root directory of asset storage
public int WebSocketPort; // port to open WebSocket listener
public bool MergeStaticMeshes; // whether to merge meshes with similar materials
public bool MergeNonStaticMeshes; // whether to merge meshes with non-static entities
public string GltfTargetDir; // where to store all the Gltf files
public bool ExportTextures; // also export textures to the target dir
public int MaxTextureSize; // the maximum pixel dimension for images if exporting
public bool AddTerrainMesh; // whether to create and add a terrain mesh
public bool CreateTerrainSplat; // whether to generate a terrain mesh splat texture
public int VerticesMaxForBuffer; // Number of vertices to cause splitting of buffer files
public bool HalfRezTerrain; // whether to reduce the terrain resolution by 2
public bool DisplayTimeScaling; // 'true' if to delay mesh scaling to display/GPU time
public string URIBase; // the URI base to be added to the beginning of the asset name
public bool UseOpenSimImageDecoder; // Use the OpenSimulator image decoder to process JPEG2000 images
public bool LogConversionStats; // output numbers about number of entities converted
public bool LogDetailedSharedFaceStats; // output numbers about face mesh sharing
public bool LogDetailedEntityInfo; // output detailed information about each entity
#pragma warning restore CS0649
// =====================================================================================
// =====================================================================================
// List of all of the externally visible parameters.
// For each parameter, this table maps a text name to getter and setters.
// To add a new externally referencable/settable parameter, add the paramter storage
// location somewhere in the program and make an entry in this table with the
// getters and setters.
// It is easiest to find an existing definition and copy it.
//
// A ParameterDefn<T>() takes the following parameters:
// -- the text name of the parameter. This is used for console input and ini file.
// -- a short text description of the parameter. This shows up in the console listing.
// -- a default value
// -- a delegate for getting the value
// -- a delegate for setting the value
// -- an optional delegate to update the value in the world. Most often used to
// push the new value to an in-world object.
//
// The single letter parameters for the delegates are:
// v = value (appropriate type)
private ParameterDefnBase[] ParameterDefinitions =
{
https://github.com/fclp/fluent-command-line-parser/wiki/Roadmap new ParameterDefn<bool>("Enabled", "If false, module is not enabled to operate",
false ),
new ParameterDefn<string>("AssetDirectory", "The directory (relative to simulator) to hold Basil assets",
"./BasilAssets" ),
new ParameterDefn<int>("WebSocketPort", "Port for the WebSocket to listen on",
34343 ),
new ParameterDefn<bool>("MergeStaticMeshes", "whether to merge meshes with similar materials",
true ),
new ParameterDefn<bool>("MergeNonStaticMeshes", "whether to merge meshes within non-static entities ",
true ),
new ParameterDefn<string>("GltfTargetDir", "Where to store all the Gltf files",
"./gltf" ),
new ParameterDefn<bool>("ExportTextures", "Convert textures to PNGs and export to target dir",
true ),
new ParameterDefn<int>("MaxTextureSize", "The maximum pixel dimension for images if exporting",
256 ),
new ParameterDefn<bool>("AddTerrainMesh", "whether to create and add a terrain mesh",
true ),
new ParameterDefn<bool>("CreateTerrainSplat", "whether to generate a terrain mesh splat texture",
true ),
new ParameterDefn<int>("VerticesMaxForBuffer", "Number of vertices to cause splitting of buffer files",
50000 ),
new ParameterDefn<bool>("HalfRezTerrain", "Whether to reduce the terrain resolution by 2",
false ),
new ParameterDefn<bool>("DisplayTimeScaling", "If to delay mesh scaling to display/GPU time",
false ),
new ParameterDefn<string>("URIBase", "the string added to be beginning of asset name to create URI",
"./" ),
new ParameterDefn<bool>("UseOpenSimImageDecoder", "Use the OpenSimulator image decoder to process JPEG2000 images",
false ),
new ParameterDefn<bool>("LogConversionStats", "output numbers about number of entities converted",
true ),
new ParameterDefn<bool>("LogDetailedSharedFaceStats", "output numbers about face mesh sharing",
true ),
new ParameterDefn<bool>("LogDetailedEntityInfo", "output detailed information about each entity",
false ),
};
// =====================================================================================
// =====================================================================================
// Base parameter definition that gets and sets parameter values via a string
public abstract class ParameterDefnBase {
public string name; // string name of the parameter
public string desc; // a short description of what the parameter means
public string[] symbols; // command line symbols for this parameter (short forms)
public ConvoarParams context; // context for setting and getting values
public ParameterDefnBase(string pName, string pDesc, string[] pSymbols) {
name = pName;
desc = pDesc;
symbols = pSymbols;
}
// Set the parameter value to the default
public abstract void AssignDefault();
// Get the value as a string
public abstract string GetValue();
// Set the value to this string value
public abstract void SetValue(string valAsString);
}
// Specific parameter definition for a parameter of a specific type.
public delegate T PGetValue<T>();
public delegate void PSetValue<T>(T val);
public sealed class ParameterDefn<T> : ParameterDefnBase {
private T defaultValue;
private PSetValue<T> setter;
private PGetValue<T> getter;
public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue<T> pGetter, PSetValue<T> pSetter, params string[] symbols)
: base(pName, pDesc, symbols) {
defaultValue = pDefault;
setter = pSetter;
getter = pGetter;
}
// Simple parameter variable where property name is the same as the INI file name
// and the value is only a simple get and set.
public ParameterDefn(string pName, string pDesc, T pDefault, params string[] symbols)
: base(pName, pDesc, symbols) {
defaultValue = pDefault;
setter = (v) => { SetValueByName(name, v); };
getter = () => { return GetValueByName(name); };
}
// Use reflection to find the property named 'pName' in Param and assign 'val' to same.
private void SetValueByName(string pName, T val) {
FieldInfo prop = context.GetType().GetField(pName);
if (prop == null) {
// This should only be output when someone adds a new INI parameter and misspells the name.
// m_log.ErrorFormat("{0} SetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameters name.", LogHeader, pName);
System.Console.WriteLine("{0} SetValueByName: did not find '{1}'. Verify specified field name is the same as the given INI parameters name.", _logHeader, pName);
}
else {
prop.SetValue(context, val);
}
}
// Use reflection to find the property named 'pName' in Param and return the value in same.
private T GetValueByName(string pName)
{
FieldInfo prop = context.GetType().GetField(pName);
if (prop == null) {
// This should only be output when someone adds a new INI parameter and misspells the name.
// m_log.ErrorFormat("{0} GetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameter name.", LogHeader, pName);
System.Console.WriteLine("{0} GetValueByName: did not find '{1}'. Verify specified field name is the same as the given INI parameter name.", _logHeader, pName);
}
return (T)prop.GetValue(context);
}
public override void AssignDefault() {
setter(defaultValue);
}
public override string GetValue() {
return getter().ToString();
}
public override void SetValue(string valAsString) {
// Get the generic type of the setter
Type genericType = setter.GetType().GetGenericArguments()[0];
// Find the 'Parse' method on that type
System.Reflection.MethodInfo parser = null;
try {
parser = genericType.GetMethod("Parse", new Type[] { typeof(String) } );
}
catch (Exception e) {
System.Console.WriteLine("{0} Exception getting parser for type '{1}': {2}", _logHeader, genericType, e);
parser = null;
}
if (parser != null) {
// Parse the input string
try {
T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString });
// Store the parsed value
setter(setValue);
// // m_log.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue);
}
catch {
// m_log.ErrorFormat("{0} Failed parsing parameter value '{1}' as type '{2}'", LogHeader, valAsString, genericType);
}
}
else {
// m_log.ErrorFormat("{0} Could not find parameter parser for type '{1}'", LogHeader, genericType);
}
}
}
// Search through the parameter definitions and return the matching
// ParameterDefn structure.
// Case does not matter as names are compared after converting to lower case.
// Returns 'false' if the parameter is not found.
public bool TryGetParameter(string paramName, out ParameterDefnBase defn) {
bool ret = false;
ParameterDefnBase foundDefn = null;
string pName = paramName.ToLower();
foreach (ParameterDefnBase parm in ParameterDefinitions) {
string parmL = parm.name.ToLower();
if (pName == parmL) {
foundDefn = parm;
ret = true;
}
if (parm.symbols != null) {
foreach (string sym in parm.symbols) {
if (sym == parmL) {
foundDefn = parm;
ret = true;
break;
}
}
}
if (ret) break;
}
defn = foundDefn;
return ret;
}
// Find the named parameter and set its value.
// Returns 'false' if the parameter could not be found.
public bool SetParameterValue(string paramName, string valueAsString) {
bool ret = false;
ParameterDefnBase parm;
if (TryGetParameter(paramName, out parm)) {
parm.SetValue(valueAsString);
ret = true;
}
return ret;
}
// Pass through the settable parameters and set the default values.
public void SetParameterDefaultValues() {
foreach (ParameterDefnBase parm in ParameterDefinitions) {
parm.context = this;
parm.AssignDefault();
}
}
public void MergeCommandLine(string[] args) {
MergeCommandLine(args, null, null);
}
public const string LAST_PARAM = "--LastParameter--";
public const string ERROR_PARAM = "--ErrorParameter--";
// Given parameters from the command line, read the parameters and set values specified
// <param name="args">array of command line tokens</param>
// <param name="firstOpFlag">if 'true' presume the first token in the parameter line
// is a special value that should be assigned to the keyword "--firstparam".</param>
// <param name="multipleFiles">if 'true' presume multiple specs at the end of the line
// are filenames and pack them together into a CSV string in LAST_PARAM.</param>
public bool MergeCommandLine(string[] args, string firstOpParameter, string multipleFilesParameter) {
bool ret = true; // start out assuming parsing worked
bool errorMsg = null;
bool firstOpFlag = false; // no first op
if (!String.IsNullOrEmpty(firstOpParameter)) {
firstOpFlag = true;
}
bool multipleFiles = false;
if (!String.IsNullOrEmpty(multipleFilesParameter)) {
multipleFiles = true;
}
for (int ii = 0; ii < args.Length; ii++) {
string para = args[ii];
// is this a parameter?
if (para[0] == '-') {
// is the next one a parameter?
if (ii == (args.Length - 1) || args[ii + 1][0] == '-') {
// two parameters in a row. this must be a toggle parameter
AddCommandLineParameter(para, null);
}
else {
// looks like a parameter followed by a value
AddCommandLineParameter(para, args[ii + 1]);
ii++; // skip the value we just added to the dictionary
}
}
else {
if (ii == 0 && firstOpFlag) {
// if the first thing is not a parameter, make like it's an op or something
AddCommandLineParameter(firstOpParameter, args[ii + 1]);
}
else {
if (multipleFiles) {
// Pack all remaining arguments into a comma-separated list as LAST_PARAM
StringBuilder multFiles = new StringBuilder();
for (int jj = ii; jj < args.Length; jj++) {
if (multFiles.Length != 0) {
multFiles.Append(",");
}
multFiles.Append(args[jj]);
}
AddCommandLineParameter(multipleFilesParameter, multipleFiles.ToString());
// Skip them all
ii = args.Length;
}
else {
// This token is not a keyword. If it's the last thing, place it
// into the dictionary as the last parameter. Otherwise an error.
if (ii == args.Length - 1) {
AddCommandLineParameter(LAST_PARAM, para);
}
else {
// something is wrong with the format of the parameters
AddCommandLineParameter(ERROR_PARAM, "Unknown parameter " + para);
}
}
}
}
}
return ret;
}
private bool AddCommandLineParameter(string parm, string val) {
bool ret = false;
ParameterDefnBase parmDefn;
if (TryGetParameter(parm, out parmDefn)) {
parmDefn.SetValue(val);
ret = true;
}
return ret;
}
}
}
+217
View File
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2016 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Text;
using System.Collections.Generic;
using log4net;
using OpenSim.Region.Framework.Scenes;
using OMV = OpenMetaverse;
using OMVR = OpenMetaverse.Rendering;
namespace org.herbal3d.convoar {
public class BasilStats : IDisposable {
public int numSimplePrims = 0;
public int numMeshAssets = 0;
public int numSculpties = 0;
EntityGroupStats staticStats = null;
EntityGroupStats nonStaticStats = null;
EntityGroupStats rebuiltStats = null;
EntityGroupStats rebuiltNonStaticStats = null;
public Scene m_scene;
public ILog m_log;
private static string _logHeader = "[Stats]";
public BasilStats(Scene pScene, ILog pLog) {
m_scene = pScene;
m_log = pLog;
}
/* TODO: figure out what statistics are wanted
// Gather statistics
public void ExtractStatistics(BasilModule.ReorganizedScene reorgScene) {
staticStats = StatsFromEntityGroupList("static", reorgScene.staticEntities);
nonStaticStats = StatsFromEntityGroupList("nonStatic", reorgScene.nonStaticEntities);
rebuiltStats = StatsFromEntityGroupList("rebuilt", reorgScene.rebuiltFaceEntities);
rebuiltNonStaticStats = StatsFromEntityGroupList("rebuiltNonStatic", reorgScene.rebuiltNonStaticEntities);
}
*/
public class EntityGroupStats {
public int numEntities = 0;
public int numMeshes = 0;
public int numLinksets = 0;
public int numIndices = 0;
public int numVertices = 0;
public int numMaterials = 0;
public int numTextures = 0;
}
public EntityGroupStats StatsFromEntityGroupList(string listName, EntityGroupList entityList) {
EntityGroupStats egs = new EntityGroupStats();
try {
List<OMV.Primitive.TextureEntryFace> TEFs = new List<OMV.Primitive.TextureEntryFace>();
List<OMV.UUID> TEXs = new List<OMV.UUID>();
egs.numEntities = entityList.Count;
entityList.ForEach(entity => {
if (entity.Count > 1) {
egs.numLinksets++;
}
entity.ForEach(epg => {
var ep = epg.primaryExtendePrim;
egs.numMeshes += ep.faces.Count;
foreach (FaceInfo fi in ep.faces) {
egs.numIndices += fi.indices.Count;
egs.numVertices += fi.vertexs.Count;
if (!TEFs.Contains(fi.textureEntry)) {
TEFs.Add(fi.textureEntry);
}
if (fi.textureID != null && !TEXs.Contains((OMV.UUID)fi.textureID)) {
TEXs.Add((OMV.UUID)fi.textureID);
}
}
});
});
egs.numMaterials = TEFs.Count;
egs.numTextures = TEXs.Count;
}
catch (Exception e) {
m_log.ErrorFormat("{0}: Exception computing {1} stats: {2}", "StatsFromEntityGroupList", listName, e);
}
return egs;
}
// Output the non entitiy list info
public void Log(string header) {
m_log.DebugFormat("{0} numSimplePrims={1}", header, numSimplePrims);
m_log.DebugFormat("{0} numSculpties={1}", header, numSculpties);
m_log.DebugFormat("{0} numMeshAssets={1}", header, numMeshAssets);
}
public void Log(EntityGroupStats stats, string header) {
m_log.DebugFormat("{0} numEntities={1}", header, stats.numEntities);
m_log.DebugFormat("{0} numMeshes={1}", header, stats.numMeshes);
m_log.DebugFormat("{0} numLinksets={1}", header, stats.numLinksets);
m_log.DebugFormat("{0} numIndices={1}", header, stats.numIndices);
m_log.DebugFormat("{0} numVertices={1}", header, stats.numVertices);
m_log.DebugFormat("{0} numMaterials={1}", header, stats.numMaterials);
m_log.DebugFormat("{0} numTextures={1}", header, stats.numTextures);
}
public void LogAll(string header) {
Log(header + " " + m_scene.Name);
if (staticStats != null) {
Log(staticStats, header + " " + m_scene.Name + " static");
}
if (nonStaticStats != null) {
Log(nonStaticStats, header + " " + m_scene.Name + " nonStatic");
}
if (rebuiltStats != null) {
Log(rebuiltStats, header + " " + m_scene.Name + " rebuilt");
}
if (rebuiltNonStaticStats != null) {
Log(rebuiltNonStaticStats, header + " " + m_scene.Name + " rebuiltNonStatic");
}
}
private const int indentStep = 2;
private string MI(int indent) { // short for "MakeIndent"
return _logHeader + " ".Substring(0, indent * indentStep);
}
public void DumpDetailed(EntityGroupList egl) {
DumpDetailed(1, egl);
}
public void DumpDetailed(int indent, EntityGroupList egl) {
m_log.Debug(MI(indent) + "EntityGroupList. Num entities=" + egl.Count);
egl.ForEach(eg => {
DumpDetailed(indent+1, eg);
});
}
public void DumpDetailed(int indent, EntityGroup eg) {
m_log.Debug(MI(indent) + "EntityGroup. NumExtendedPrims=" + eg.Count);
eg.ForEach(epg => {
DumpDetailed(indent+1, epg);
});
}
public void DumpDetailed(int indent, ExtendedPrimGroup epg) {
m_log.Debug(MI(indent) + "ExtendedPrimGroup");
foreach (PrimGroupType lodKey in epg.Keys) {
DumpDetailed(indent+1, lodKey, epg[lodKey]);
}
}
public void DumpDetailed(int indent, PrimGroupType lodKey, ExtendedPrim ep) {
m_log.Debug(MI(indent) + "LOD=" + lodKey);
DumpDetailed(indent+1, ep);
}
public void DumpDetailed(int indent, ExtendedPrim ep) {
var name = ep.fromOS.SOG == null ? "TERRAIN" : ep.fromOS.SOG.Name;
m_log.Debug(MI(indent) + "name=" + name);
StringBuilder buff = new StringBuilder();
buff.Append(MI(indent) + "faces=" + ep.faces.Count);
foreach (FaceInfo face in ep.faces) {
buff.Append("(");
buff.Append(face.vertexs.Count.ToString());
buff.Append("/");
buff.Append(face.indices.Count.ToString());
buff.Append("/");
var hash = face.textureEntry == null ? 0 : face.GetTextureHash();
buff.Append(hash.ToString());
if (face.textureID != null
&& face.textureID != OMV.UUID.Zero
&& face.textureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE) {
buff.Append("T");
}
buff.Append(") ");
}
m_log.Debug(buff.ToString());
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
}
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~BasilStats() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose() {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
}
+377
View File
@@ -0,0 +1,377 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using OMV = OpenMetaverse;
using OMVS = OpenMetaverse.StructuredData;
using OMVA = OpenMetaverse.Assets;
using OMVR = OpenMetaverse.Rendering;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
/*
EntityGroupList is a collection of entities in a scene
EntityGroup is a group of prims that make up a scene entity (single prim or linkset)
ExtendedPrimGroup are the lod versions of an individual prim (usually only lod1)
ExtendedPrim is an individual prim (derived from Primitive, Sculpty, or Mesh)
FaceInfo are the meshes that make up an individual prim
*/
namespace org.herbal3d.convoar {
public class CoordSystem {
public const int Handedness = 0x200; // bit that specifies the handedness
public const int UpDimension = 0x00F; // field that specifies the up dimension
public const int UVOrigin = 0x030; // field that specifies UV origin location
public const int RightHand = 0x000;
public const int LeftHand = 0x200;
public const int Yup = 0x001;
public const int Zup = 0x002;
public const int UVOriginUpperLeft = 0x000; // most of the world has origin in upper left
public const int UVOriginLowerLeft = 0x010; // OpenGL specifies UV origin in lower left
public const int RightHand_Yup = RightHand + Yup;
public const int LeftHand_Yup = LeftHand + Yup;
public const int RightHand_Zup = RightHand + Zup;
public const int LeftHand_Zup = LeftHand + Zup;
// RightHand_Zup: SL
// RightHand_Yup: OpenGL
// LeftHand_Yup: DirectX, Babylon, Unity
public int system;
public CoordSystem() {
system = RightHand_Zup; // default to SL
}
public CoordSystem(int initCoord) {
system = initCoord;
}
public int getUpDimension { get { return system & UpDimension; } }
public int getHandedness { get { return system & Handedness; } }
public int getUVOrigin { get { return system & UVOrigin; } }
public bool isHandednessChanging(CoordSystem nextSystem) {
return (system & Handedness) != (nextSystem.system & Handedness);
}
public string SystemName { get { return SystemNames[system]; } }
public static Dictionary<int, string> SystemNames = new Dictionary<int, string>() {
{ RightHand_Yup, "RightHand,Y-up" },
{ RightHand_Zup, "RightHand,Z-up" },
{ LeftHand_Yup, "LeftHand,Y-up" },
{ LeftHand_Zup, "LeftHand,Z-up" }
};
public CoordSystem clone() {
return new CoordSystem(this.system);
}
}
public class FaceInfo {
public int num; // number of this face on the prim
public List<OMVR.Vertex> vertexs;
public List<ushort> indices;
public OMV.Vector3 faceCenter;
public ExtendedPrim containingPrim;
// Information about the material decorating the vertices
public OMV.Primitive.TextureEntryFace textureEntry;
public OMV.UUID? textureID; // UUID of the texture if there is one
public Image faceImage;
public bool hasAlpha; // true if there is some transparancy in the surface
public bool fullAlpha; // true if the alpha is everywhere
// public string imageFilename; // filename built for this face material
// public string imageURI; // URI built for this face material
public BasilPersist persist; // Information on persisting the image as a file and an URI
private static OMV.Primitive.TextureEntryFace DefaultWhite =
new OMV.Primitive.TextureEntryFace(null) { TextureID = OMV.Primitive.TextureEntry.WHITE_TEXTURE };
public FaceInfo(int pNum, ExtendedPrim pContainingPrim) {
Init(pNum, pContainingPrim);
}
public FaceInfo(int pNum, ExtendedPrim pContainingPrim, OMVR.Face aFace, OMV.Primitive.TextureEntryFace tef) {
Init(pNum, pContainingPrim);
vertexs = aFace.Vertices.ToList();
indices = aFace.Indices.ToList();
faceCenter = aFace.Center;
textureEntry = tef;
if (tef.RGBA.A != 1f) {
fullAlpha = true;
}
}
private void Init(int pNum, ExtendedPrim pContainingPrim) {
num = pNum;
containingPrim = pContainingPrim;
vertexs = new List<OMVR.Vertex>();
indices = new List<ushort>();
faceCenter = OMV.Vector3.Zero;
// textureEntry = DefaultWhite;
hasAlpha = false;
fullAlpha = false;
faceImage = null; // flag saying if an image is present
textureID = null; // flag saying if an image is present
}
// TextureEntryFace.GetHashCode() includes all the texture displacement which is
// really already applied to the UV of the mesh.
// This is a truncated version of the hash computation in TextureEntryFace.
public int GetTextureHash() {
int hash = 0;
if (textureEntry != null) {
hash =
textureEntry.RGBA.GetHashCode() ^
// textureEntry.RepeatU.GetHashCode() ^
// textureEntry.RepeatV.GetHashCode() ^
// textureEntry.OffsetU.GetHashCode() ^
// textureEntry.OffsetV.GetHashCode() ^
// textureEntry.Rotation.GetHashCode() ^
textureEntry.Glow.GetHashCode() ^
textureEntry.Bump.GetHashCode() ^
textureEntry.Shiny.GetHashCode() ^
textureEntry.Fullbright.GetHashCode() ^
textureEntry.MediaFlags.GetHashCode() ^
textureEntry.TexMapType.GetHashCode() ^
textureEntry.TextureID.GetHashCode() ^
textureEntry.MaterialID.GetHashCode();
}
else {
var rnd = new Random();
hash = rnd.Next();
}
return hash;
}
}
// An extended description of an entity that includes the original
// prim description as well as the mesh.
// All the information about the meshed piece is collected here so other mappings
// can happen with the returned information (creating Basil Entitities, etc)
public class ExtendedPrim {
public struct FromOSEntities {
// This separates pointers into OpenSimulator structures so it is
// easy to find the references. All info should be copied into
// the ExtendedPrim when created so these are here for debugging mostly.
public SceneObjectGroup SOG { get; set; }
public SceneObjectPart SOP { get; set; }
public OMV.Primitive primitive { get; set; }
public OMVR.FacetedMesh facetedMesh { get; set; }
};
public FromOSEntities fromOS;
public OMV.UUID ID;
public string Name;
public CoordSystem coordSystem; // coordinate system of this prim
public OMV.Vector3 translation;
public OMV.Quaternion rotation;
public OMV.Vector3 scale;
public OMV.Matrix4? transform;
public bool positionIsParentRelative;
// The data is taken out of the structures above and copied here for mangling
public List<FaceInfo> faces;
// This logic is here mostly because there are some entities that are not scene objects.
// Terrain, in particular.
// Someone can force root state by setting this value otherwise the rootedness of the underlying
// SOP is used.
private bool? m_isRoot = null;
public bool isRoot {
get {
bool ret = true;
if (m_isRoot == null) {
if (fromOS.SOP != null && !fromOS.SOP.IsRoot)
ret = false;
}
else {
ret = (bool)m_isRoot;
}
return ret;
}
set {
m_isRoot = value;
}
}
// A very empty ExtendedPrim. You must initialize everything by hand after creating this.
public ExtendedPrim() {
transform = null;
coordSystem = new CoordSystem(CoordSystem.RightHand_Zup); // default to SL coordinates
faces = new List<FaceInfo>();
}
// Make a new extended prim based on an existing one
public ExtendedPrim(ExtendedPrim ep) : this(ep.fromOS.SOG, ep.fromOS.SOP, ep.fromOS.primitive, ep.fromOS.facetedMesh) {
}
// Initialize an ExtendedPrim from the OpenSimulator structures.
// Note that the translation and rotation are copied into the ExtendedPrim for later coordinate modification.
public ExtendedPrim(SceneObjectGroup pSOG, SceneObjectPart pSOP, OMV.Primitive pPrim, OMVR.FacetedMesh pFMesh) {
fromOS.SOG = pSOG;
fromOS.SOP = pSOP;
fromOS.primitive = pPrim;
fromOS.facetedMesh = pFMesh;
translation = new OMV.Vector3(0, 0, 0);
rotation = OMV.Quaternion.Identity;
scale = OMV.Vector3.One;
transform = null; // matrix overrides the translation/rotation. Start with no matrix.
coordSystem = new CoordSystem(CoordSystem.RightHand_Zup); // default to SL coordinates
if (fromOS.SOP != null) {
ID = fromOS.SOP.UUID;
Name = fromOS.SOP.Name;
}
else {
ID = OMV.UUID.Random();
Name = "Custom";
}
if (fromOS.SOP != null) {
if (fromOS.SOP.IsRoot) {
translation = fromOS.SOP.GetWorldPosition();
rotation = fromOS.SOP.GetWorldRotation();
positionIsParentRelative = false;
}
else {
translation = fromOS.SOP.OffsetPosition;
rotation = fromOS.SOP.RotationOffset;
positionIsParentRelative = true;
}
scale = fromOS.SOP.Scale;
}
// Copy the vertex information into our face information array.
// Only the vertex and indices information is put into the face info.
// The texture info must be added later.
faces = new List<FaceInfo>();
if (pPrim != null) {
for (int ii = 0; ii < pFMesh.Faces.Count; ii++) {
OMV.Primitive.TextureEntryFace tef = pPrim.Textures.FaceTextures[ii];
if (tef == null) {
tef = pPrim.Textures.DefaultTexture;
}
OMVR.Face aFace = pFMesh.Faces[ii];
FaceInfo faceInfo = new FaceInfo(ii, this, aFace, tef);
faces.Add(faceInfo);
}
}
}
public override int GetHashCode() {
int ret = 0;
if (fromOS.primitive != null) {
ret = fromOS.primitive.GetHashCode();
}
else {
ret = base.GetHashCode();
}
return ret;
}
public string Stats() {
StringBuilder buff = new StringBuilder();
buff.Append("ep:faces=" + this.faces.Count.ToString());
return buff.ToString();
}
};
// A prim mesh can be made up of many versions
public enum PrimGroupType {
physics,
lod1, // this is default and what is built for a standard prim
lod2,
lod3,
lod4
};
// Some prims (like the mesh type) have multiple versions to make one entity
public class ExtendedPrimGroup: Dictionary<PrimGroupType, ExtendedPrim> {
public ExtendedPrimGroup() : base() {
}
// Create with a single prim
public ExtendedPrimGroup(ExtendedPrim singlePrim) : base() {
this.Add(PrimGroupType.lod1, singlePrim);
}
// Return the primary version of this prim which is the highest LOD verstion.
public ExtendedPrim primaryExtendePrim {
get {
ExtendedPrim ret = null;
this.TryGetValue(PrimGroupType.lod1, out ret);
return ret;
}
}
public string Stats() {
StringBuilder buff = new StringBuilder();
buff.Append("epg:lods=" + this.Keys.Count.ToString());
buff.Append(",");
buff.Append(this.primaryExtendePrim.Stats());
return buff.ToString();
}
}
// some entities are made of multiple prims (linksets)
public class EntityGroup : List<ExtendedPrimGroup> {
public EntityGroup() : base() {
}
public EntityGroup(List<ExtendedPrimGroup> list) : base(list) {
}
public string Stats() {
StringBuilder buff = new StringBuilder();
buff.Append("EntityGroup: cnt=" + this.Count.ToString() + ":");
this.ForEach(epg => {
buff.Append(epg.Stats());
buff.Append(",");
});
return buff.ToString();
}
}
// list of entities
public class EntityGroupList : List<EntityGroup> {
public EntityGroupList() : base() {
}
public EntityGroupList(EntityGroupList list) : base(list) {
}
public EntityGroupList(List<EntityGroup> list) : base(list) {
}
// Add the entity group to the list if it is not alreayd in the list
public bool AddUniqueEntity(EntityGroup added) {
bool ret = false;
if (!base.Contains(added)) {
base.Add(added);
ret = true;
}
return ret;
}
// Perform an action on every extended prim in this EntityGroupList
public void ForEachExtendedPrim(Action<ExtendedPrim> aeg) {
this.ForEach(eGroup => {
eGroup.ForEach(ePGroup => {
ExtendedPrim ep = ePGroup.primaryExtendePrim; // the interesting one is the high rez one
aeg(ep);
});
});
}
}
}
+79
View File
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using OMV = OpenMetaverse;
namespace org.herbal3d.convoar {
// Class for collecting all me mess around asset names.
// All filename, type, and version conversions are done here.
//
// At the moment, an entity just has a UUID
public class EntityHandle : IEqualityComparer<EntityHandle> {
OMV.UUID m_uuid;
public EntityHandle(OMV.UUID id) {
m_uuid = id;
}
// OpenSim likes to specify assets with a simple string of the asset's UUID
public string GetOSAssetString() {
return m_uuid.ToString();
}
public OMV.UUID GetUUID() {
return m_uuid;
}
public override string ToString() {
return m_uuid.ToString();
}
// IComparable
public int CompareTo(object obj) {
int ret = 0;
EntityHandle other = obj as EntityHandle;
if (other == null) {
throw new ArgumentException("CompareTo in EntityHandle: other type not EntityHandle");
}
if (this.m_uuid != other.m_uuid) {
string thisOne = this.m_uuid.ToString();
string otherOne = this.m_uuid.ToString();
ret = thisOne.CompareTo(otherOne);
}
return ret;
}
// System.Object.GetHashCode()
public override int GetHashCode() {
return m_uuid.GetHashCode();
}
// IEqualityComparer.Equals
public bool Equals(EntityHandle x, EntityHandle y) {
return x.m_uuid.CompareTo(y.m_uuid) == 0;
}
// IEqualityComparer.GetHashCode
public int GetHashCode(EntityHandle obj) {
return obj.m_uuid.GetHashCode();
}
}
}
+1382
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -24,14 +24,14 @@ using log4net;
namespace org.herbal3d.convoar {
// One place to put all the logging routines
public static class Logger {
public class Logger {
private static readonly ILog _log = LogManager.GetLogger("convoar");
private static bool _verbose = false;
public static bool Verbose {
private bool _verbose = false;
public bool Verbose {
get { return _verbose; }
set {
bool nextValue = value;
set {
bool nextValue = value;
if (!_verbose && nextValue) {
// turning Verbose on
LogManager.GetRepository().Threshold = log4net.Core.Level.Debug;
@@ -44,20 +44,20 @@ namespace org.herbal3d.convoar {
}
}
public static void Log(string msg, params Object[] args) {
public void Log(string msg, params Object[] args) {
_log.InfoFormat(msg, args);
// System.Console.WriteLine(msg, args);
}
// Output the message if 'Verbose' is true
public static void LogDebug(string msg, params Object[] args) {
public void LogDebug(string msg, params Object[] args) {
_log.DebugFormat(msg, args);
// if (Verbose) {
// System.Console.WriteLine(msg, args);
// }
}
public static void LogError(string msg, params Object[] args) {
public void LogError(string msg, params Object[] args) {
_log.ErrorFormat(msg, args);
// System.Console.WriteLine(msg, args);
}
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenMetaverse;
using OpenSim.Services.Interfaces;
namespace org.herbal3d.convoar {
// A dummy class used to fool OpenSimulator routines that there is a real user account service
class NullUserAccountService : IUserAccountService
{
public UserAccount GetUserAccount(UUID scopeID, UUID userID) {
UserAccount ua = new UserAccount(scopeID, userID, "firstname", "lastname", "firstname.lastname@example.com");
return ua;
}
public UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName) {
UserAccount ua = new UserAccount(scopeID, FirstName, LastName, "firstname.lastname@example.com");
return ua;
}
public UserAccount GetUserAccount(UUID scopeID, string Email) {
UserAccount ua = new UserAccount(scopeID, "firstname", "lastname", Email);
return ua;
}
public List<UserAccount> GetUserAccounts(UUID scopeID, string query) {
UserAccount ua = new UserAccount(scopeID, "firstname", "lastname", "firstname.lastname@example.com");
return new List<UserAccount>() { ua } ;
}
public List<UserAccount> GetUserAccounts(UUID scopeID, List<string> IDs) {
UserAccount ua = new UserAccount(scopeID, "firstname", "lastname", "firstname.lastname@example.com");
return new List<UserAccount>() { ua } ;
throw new NotImplementedException();
}
public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where) {
throw new NotImplementedException();
}
public void InvalidateCache(UUID userID) {
throw new NotImplementedException();
}
public bool StoreUserAccount(UserAccount data) {
throw new NotImplementedException();
}
}
}
+221
View File
@@ -0,0 +1,221 @@
/*
* Copyright (c) 2016 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using log4net;
using RSG;
using OMV = OpenMetaverse;
using OMVS = OpenMetaverse.StructuredData;
using OMVA = OpenMetaverse.Assets;
using OMVR = OpenMetaverse.Rendering;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
namespace org.herbal3d.convoar {
public class PrimToMesh : IDisposable {
private OMVR.MeshmerizerR m_mesher;
ILog _log;
String _logHeader = "[Basil.PrimToMesh]";
public PrimToMesh(ILog logger) {
m_mesher = new OMVR.MeshmerizerR();
_log = logger;
}
/// <summary>
/// Create and return a faceted mesh.
/// </summary>
public IPromise<ExtendedPrimGroup> CreateMeshResource(SceneObjectGroup sog, SceneObjectPart sop,
OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod, BasilStats stats) {
var prom = new Promise<ExtendedPrimGroup>();
ExtendedPrimGroup mesh;
try {
if (prim.Sculpt != null) {
if (prim.Sculpt.Type == OMV.SculptType.Mesh) {
// m_log.DebugFormat("{0}: CreateMeshResource: creating mesh", LogHeader);
stats.numMeshAssets++;
MeshFromPrimMeshData(sog, sop, prim, assetFetcher, lod)
.Catch(e => {
prom.Reject(e);
})
.Then(ePrimGroup => {
prom.Resolve(ePrimGroup);
});
}
else {
// m_log.DebugFormat("{0}: CreateMeshResource: creating sculpty", LogHeader);
stats.numSculpties++;
MeshFromPrimSculptData(sog, sop, prim, assetFetcher, lod)
.Catch(e => {
prom.Reject(e);
})
.Then(fm => {
prom.Resolve(fm);
});
}
}
else {
// m_log.DebugFormat("{0}: CreateMeshResource: creating primshape", LogHeader);
stats.numSimplePrims++;
mesh = MeshFromPrimShapeData(sog, sop, prim, lod);
prom.Resolve(mesh);
}
}
catch (Exception e) {
prom.Reject(e);
}
return prom;
}
private ExtendedPrimGroup MeshFromPrimShapeData(SceneObjectGroup sog, SceneObjectPart sop,
OMV.Primitive prim, OMVR.DetailLevel lod) {
OMVR.FacetedMesh mesh;
mesh = m_mesher.GenerateFacetedMesh(prim, lod);
ExtendedPrim extPrim = new ExtendedPrim(sog, sop, prim, mesh);
ExtendedPrimGroup extPrimGroup = new ExtendedPrimGroup(extPrim);
return extPrimGroup;
}
private IPromise<ExtendedPrimGroup> MeshFromPrimSculptData(SceneObjectGroup sog, SceneObjectPart sop,
OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) {
var prom = new Promise<ExtendedPrimGroup>();
// Get the asset that the sculpty is built on
EntityHandle texHandle = new EntityHandle(prim.Sculpt.SculptTexture);
assetFetcher.FetchTexture(texHandle)
.Then((bm) => {
OMVR.FacetedMesh fMesh = m_mesher.GenerateFacetedSculptMesh(prim, bm.Image.ExportBitmap(), lod);
ExtendedPrim extPrim = new ExtendedPrim(sog, sop, prim, fMesh);
ExtendedPrimGroup extPrimGroup = new ExtendedPrimGroup(extPrim);
prom.Resolve(extPrimGroup);
})
.Catch((e) => {
_log.ErrorFormat("{0} MeshFromPrimSculptData: Rejected FetchTexture: {1}: {2}", _logHeader, texHandle, e);
prom.Reject(e);
});
return prom;
}
private IPromise<ExtendedPrimGroup> MeshFromPrimMeshData(SceneObjectGroup sog, SceneObjectPart sop,
OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) {
var prom = new Promise<ExtendedPrimGroup>();
// Get the asset that the mesh is built on
EntityHandle meshHandle = new EntityHandle(prim.Sculpt.SculptTexture);
try {
assetFetcher.FetchRawAsset(meshHandle)
.Then(meshBytes => {
OMVA.AssetMesh meshAsset = new OMVA.AssetMesh(prim.ID, meshBytes);
OMVR.FacetedMesh fMesh;
if (OMVR.FacetedMesh.TryDecodeFromAsset(prim, meshAsset, lod, out fMesh)) {
ExtendedPrim extPrim = new ExtendedPrim(sog, sop, prim, fMesh);
ExtendedPrimGroup eGroup = new ExtendedPrimGroup(extPrim);
prom.Resolve(eGroup);
}
else {
prom.Reject(new Exception("MeshFromPrimMeshData: could not decode mesh information from asset. ID="
+ prim.ID.ToString()));
}
})
.Catch((e) => {
_log.ErrorFormat("{0} MeshFromPrimSculptData: Rejected FetchTexture: {1}", _logHeader, e);
prom.Reject(e);
});
}
catch (Exception e) {
prom.Reject(e);
}
return prom;
}
// Returns an ExtendedPrimGroup with a mesh for the passed heightmap.
// Note that the returned EPG does not include any face information -- the caller must add a texture.
public ExtendedPrimGroup MeshFromHeightMap( float[,] pHeightMap, int regionSizeX, int regionSizeY) {
// OMVR.Face rawMesh = m_mesher.TerrainMesh(pHeightMap, 0, pHeightMap.GetLength(0)-1, 0, pHeightMap.GetLength(1)-1);
_log.DebugFormat("{0} MeshFromHeightMap: heightmap=<{1},{2}>, regionSize=<{3},{4}>",
_logHeader, pHeightMap.GetLength(0), pHeightMap.GetLength(1), regionSizeX, regionSizeY);
OMVR.Face rawMesh = BasilTerrain.TerrainMesh(pHeightMap, (float)regionSizeX, (float)regionSizeY, _log);
OMVR.FacetedMesh facetMesh = new OMVR.FacetedMesh();
facetMesh.Faces = new List<OMVR.Face>() { rawMesh };
ExtendedPrim ep = new ExtendedPrim(null, null, null, facetMesh);
ep.faces = new List<FaceInfo>();
ExtendedPrimGroup epg = new ExtendedPrimGroup(ep);
return epg;
}
public void Dispose() {
m_mesher = null;
}
public void UpdateCoords(FaceInfo faceInfo, OMV.Primitive prim) {
if (faceInfo.vertexs != null) {
m_mesher.TransformTexCoords(faceInfo.vertexs, faceInfo.faceCenter, faceInfo.textureEntry, prim.Scale);
}
}
// Walk through all the vertices and scale the included meshes
public static void ScaleMeshes(ExtendedPrimGroup ePG) {
foreach (ExtendedPrim ep in ePG.Values) {
OMV.Vector3 scale = ep.fromOS.primitive.Scale;
if (scale.X != 1.0 || scale.Y != 1.0 || scale.Z != 1.0) {
OnAllVertex(ep, delegate (ref OMVR.Vertex vert) {
vert.Position *= scale;
});
}
}
}
// Loop over all the vertices in an ExtendedPrim and perform some operation on them
public delegate void OperateOnVertex(ref OMVR.Vertex vert);
public static void OnAllVertex(ExtendedPrim ep, OperateOnVertex vertOp) {
foreach (FaceInfo aFace in ep.faces) {
for (int jj = 0; jj < aFace.vertexs.Count; jj++) {
OMVR.Vertex aVert = aFace.vertexs[jj];
vertOp(ref aVert);
aFace.vertexs[jj] = aVert;
}
}
}
}
}
+596
View File
@@ -0,0 +1,596 @@
/*
* Copyright (c) 2017 Robert Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Derived from WebGLConstants.js from Cesium project. (Apache 2.0)
namespace org.herbal3d.convoar {
public class WebGLConstants {
public const uint DEPTH_BUFFER_BIT = 0x00000100;
public const uint STENCIL_BUFFER_BIT = 0x00000400;
public const uint COLOR_BUFFER_BIT = 0x00004000;
public const uint POINTS = 0x0000;
public const uint LINES = 0x0001;
public const uint LINE_LOOP = 0x0002;
public const uint LINE_STRIP = 0x0003;
public const uint TRIANGLES = 0x0004;
public const uint TRIANGLE_STRIP = 0x0005;
public const uint TRIANGLE_FAN = 0x0006;
public const uint ZERO = 0;
public const uint ONE = 1;
public const uint SRC_COLOR = 0x0300;
public const uint ONE_MINUS_SRC_COLOR = 0x0301;
public const uint SRC_ALPHA = 0x0302;
public const uint ONE_MINUS_SRC_ALPHA = 0x0303;
public const uint DST_ALPHA = 0x0304;
public const uint ONE_MINUS_DST_ALPHA = 0x0305;
public const uint DST_COLOR = 0x0306;
public const uint ONE_MINUS_DST_COLOR = 0x0307;
public const uint SRC_ALPHA_SATURATE = 0x0308;
public const uint FUNC_ADD = 0x8006;
public const uint BLEND_EQUATION = 0x8009;
public const uint BLEND_EQUATION_RGB = 0x8009; // same as BLEND_EQUATION
public const uint BLEND_EQUATION_ALPHA = 0x883D;
public const uint FUNC_SUBTRACT = 0x800A;
public const uint FUNC_REVERSE_SUBTRACT = 0x800B;
public const uint BLEND_DST_RGB = 0x80C8;
public const uint BLEND_SRC_RGB = 0x80C9;
public const uint BLEND_DST_ALPHA = 0x80CA;
public const uint BLEND_SRC_ALPHA = 0x80CB;
public const uint CONSTANT_COLOR = 0x8001;
public const uint ONE_MINUS_CONSTANT_COLOR = 0x8002;
public const uint CONSTANT_ALPHA = 0x8003;
public const uint ONE_MINUS_CONSTANT_ALPHA = 0x8004;
public const uint BLEND_COLOR = 0x8005;
public const uint ARRAY_BUFFER = 0x8892;
public const uint ELEMENT_ARRAY_BUFFER = 0x8893;
public const uint ARRAY_BUFFER_BINDING = 0x8894;
public const uint ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
public const uint STREAM_DRAW = 0x88E0;
public const uint STATIC_DRAW = 0x88E4;
public const uint DYNAMIC_DRAW = 0x88E8;
public const uint BUFFER_SIZE = 0x8764;
public const uint BUFFER_USAGE = 0x8765;
public const uint CURRENT_VERTEX_ATTRIB = 0x8626;
public const uint FRONT = 0x0404;
public const uint BACK = 0x0405;
public const uint FRONT_AND_BACK = 0x0408;
public const uint CULL_FACE = 0x0B44;
public const uint BLEND = 0x0BE2;
public const uint DITHER = 0x0BD0;
public const uint STENCIL_TEST = 0x0B90;
public const uint DEPTH_TEST = 0x0B71;
public const uint SCISSOR_TEST = 0x0C11;
public const uint POLYGON_OFFSET_FILL = 0x8037;
public const uint SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
public const uint SAMPLE_COVERAGE = 0x80A0;
public const uint NO_ERROR = 0;
public const uint INVALID_ENUM = 0x0500;
public const uint INVALID_VALUE = 0x0501;
public const uint INVALID_OPERATION = 0x0502;
public const uint OUT_OF_MEMORY = 0x0505;
public const uint CW = 0x0900;
public const uint CCW = 0x0901;
public const uint LINE_WIDTH = 0x0B21;
public const uint ALIASED_POINT_SIZE_RANGE = 0x846D;
public const uint ALIASED_LINE_WIDTH_RANGE = 0x846E;
public const uint CULL_FACE_MODE = 0x0B45;
public const uint FRONT_FACE = 0x0B46;
public const uint DEPTH_RANGE = 0x0B70;
public const uint DEPTH_WRITEMASK = 0x0B72;
public const uint DEPTH_CLEAR_VALUE = 0x0B73;
public const uint DEPTH_FUNC = 0x0B74;
public const uint STENCIL_CLEAR_VALUE = 0x0B91;
public const uint STENCIL_FUNC = 0x0B92;
public const uint STENCIL_FAIL = 0x0B94;
public const uint STENCIL_PASS_DEPTH_FAIL = 0x0B95;
public const uint STENCIL_PASS_DEPTH_PASS = 0x0B96;
public const uint STENCIL_REF = 0x0B97;
public const uint STENCIL_VALUE_MASK = 0x0B93;
public const uint STENCIL_WRITEMASK = 0x0B98;
public const uint STENCIL_BACK_FUNC = 0x8800;
public const uint STENCIL_BACK_FAIL = 0x8801;
public const uint STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
public const uint STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
public const uint STENCIL_BACK_REF = 0x8CA3;
public const uint STENCIL_BACK_VALUE_MASK = 0x8CA4;
public const uint STENCIL_BACK_WRITEMASK = 0x8CA5;
public const uint VIEWPORT = 0x0BA2;
public const uint SCISSOR_BOX = 0x0C10;
public const uint COLOR_CLEAR_VALUE = 0x0C22;
public const uint COLOR_WRITEMASK = 0x0C23;
public const uint UNPACK_ALIGNMENT = 0x0CF5;
public const uint PACK_ALIGNMENT = 0x0D05;
public const uint MAX_TEXTURE_SIZE = 0x0D33;
public const uint MAX_VIEWPORT_DIMS = 0x0D3A;
public const uint SUBPIXEL_BITS = 0x0D50;
public const uint RED_BITS = 0x0D52;
public const uint GREEN_BITS = 0x0D53;
public const uint BLUE_BITS = 0x0D54;
public const uint ALPHA_BITS = 0x0D55;
public const uint DEPTH_BITS = 0x0D56;
public const uint STENCIL_BITS = 0x0D57;
public const uint POLYGON_OFFSET_UNITS = 0x2A00;
public const uint POLYGON_OFFSET_FACTOR = 0x8038;
public const uint TEXTURE_BINDING_2D = 0x8069;
public const uint SAMPLE_BUFFERS = 0x80A8;
public const uint SAMPLES = 0x80A9;
public const uint SAMPLE_COVERAGE_VALUE = 0x80AA;
public const uint SAMPLE_COVERAGE_INVERT = 0x80AB;
public const uint COMPRESSED_TEXTURE_FORMATS = 0x86A3;
public const uint DONT_CARE = 0x1100;
public const uint FASTEST = 0x1101;
public const uint NICEST = 0x1102;
public const uint GENERATE_MIPMAP_HINT = 0x8192;
public const uint BYTE = 0x1400;
public const uint UNSIGNED_BYTE = 0x1401;
public const uint SHORT = 0x1402;
public const uint UNSIGNED_SHORT = 0x1403;
public const uint INT = 0x1404;
public const uint UNSIGNED_INT = 0x1405;
public const uint FLOAT = 0x1406;
public const uint DEPTH_COMPONENT = 0x1902;
public const uint ALPHA = 0x1906;
public const uint RGB = 0x1907;
public const uint RGBA = 0x1908;
public const uint LUMINANCE = 0x1909;
public const uint LUMINANCE_ALPHA = 0x190A;
public const uint UNSIGNED_SHORT_4_4_4_4 = 0x8033;
public const uint UNSIGNED_SHORT_5_5_5_1 = 0x8034;
public const uint UNSIGNED_SHORT_5_6_5 = 0x8363;
public const uint FRAGMENT_SHADER = 0x8B30;
public const uint VERTEX_SHADER = 0x8B31;
public const uint MAX_VERTEX_ATTRIBS = 0x8869;
public const uint MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
public const uint MAX_VARYING_VECTORS = 0x8DFC;
public const uint MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
public const uint MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
public const uint MAX_TEXTURE_IMAGE_UNITS = 0x8872;
public const uint MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
public const uint SHADER_TYPE = 0x8B4F;
public const uint DELETE_STATUS = 0x8B80;
public const uint LINK_STATUS = 0x8B82;
public const uint VALIDATE_STATUS = 0x8B83;
public const uint ATTACHED_SHADERS = 0x8B85;
public const uint ACTIVE_UNIFORMS = 0x8B86;
public const uint ACTIVE_ATTRIBUTES = 0x8B89;
public const uint SHADING_LANGUAGE_VERSION = 0x8B8C;
public const uint CURRENT_PROGRAM = 0x8B8D;
public const uint NEVER = 0x0200;
public const uint LESS = 0x0201;
public const uint EQUAL = 0x0202;
public const uint LEQUAL = 0x0203;
public const uint GREATER = 0x0204;
public const uint NOTEQUAL = 0x0205;
public const uint GEQUAL = 0x0206;
public const uint ALWAYS = 0x0207;
public const uint KEEP = 0x1E00;
public const uint REPLACE = 0x1E01;
public const uint INCR = 0x1E02;
public const uint DECR = 0x1E03;
public const uint INVERT = 0x150A;
public const uint INCR_WRAP = 0x8507;
public const uint DECR_WRAP = 0x8508;
public const uint VENDOR = 0x1F00;
public const uint RENDERER = 0x1F01;
public const uint VERSION = 0x1F02;
public const uint NEAREST = 0x2600;
public const uint LINEAR = 0x2601;
public const uint NEAREST_MIPMAP_NEAREST = 0x2700;
public const uint LINEAR_MIPMAP_NEAREST = 0x2701;
public const uint NEAREST_MIPMAP_LINEAR = 0x2702;
public const uint LINEAR_MIPMAP_LINEAR = 0x2703;
public const uint TEXTURE_MAG_FILTER = 0x2800;
public const uint TEXTURE_MIN_FILTER = 0x2801;
public const uint TEXTURE_WRAP_S = 0x2802;
public const uint TEXTURE_WRAP_T = 0x2803;
public const uint TEXTURE_2D = 0x0DE1;
public const uint TEXTURE = 0x1702;
public const uint TEXTURE_CUBE_MAP = 0x8513;
public const uint TEXTURE_BINDING_CUBE_MAP = 0x8514;
public const uint TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
public const uint TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
public const uint TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
public const uint TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
public const uint TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
public const uint TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
public const uint MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
public const uint TEXTURE0 = 0x84C0;
public const uint TEXTURE1 = 0x84C1;
public const uint TEXTURE2 = 0x84C2;
public const uint TEXTURE3 = 0x84C3;
public const uint TEXTURE4 = 0x84C4;
public const uint TEXTURE5 = 0x84C5;
public const uint TEXTURE6 = 0x84C6;
public const uint TEXTURE7 = 0x84C7;
public const uint TEXTURE8 = 0x84C8;
public const uint TEXTURE9 = 0x84C9;
public const uint TEXTURE10 = 0x84CA;
public const uint TEXTURE11 = 0x84CB;
public const uint TEXTURE12 = 0x84CC;
public const uint TEXTURE13 = 0x84CD;
public const uint TEXTURE14 = 0x84CE;
public const uint TEXTURE15 = 0x84CF;
public const uint TEXTURE16 = 0x84D0;
public const uint TEXTURE17 = 0x84D1;
public const uint TEXTURE18 = 0x84D2;
public const uint TEXTURE19 = 0x84D3;
public const uint TEXTURE20 = 0x84D4;
public const uint TEXTURE21 = 0x84D5;
public const uint TEXTURE22 = 0x84D6;
public const uint TEXTURE23 = 0x84D7;
public const uint TEXTURE24 = 0x84D8;
public const uint TEXTURE25 = 0x84D9;
public const uint TEXTURE26 = 0x84DA;
public const uint TEXTURE27 = 0x84DB;
public const uint TEXTURE28 = 0x84DC;
public const uint TEXTURE29 = 0x84DD;
public const uint TEXTURE30 = 0x84DE;
public const uint TEXTURE31 = 0x84DF;
public const uint ACTIVE_TEXTURE = 0x84E0;
public const uint REPEAT = 0x2901;
public const uint CLAMP_TO_EDGE = 0x812F;
public const uint MIRRORED_REPEAT = 0x8370;
public const uint FLOAT_VEC2 = 0x8B50;
public const uint FLOAT_VEC3 = 0x8B51;
public const uint FLOAT_VEC4 = 0x8B52;
public const uint INT_VEC2 = 0x8B53;
public const uint INT_VEC3 = 0x8B54;
public const uint INT_VEC4 = 0x8B55;
public const uint BOOL = 0x8B56;
public const uint BOOL_VEC2 = 0x8B57;
public const uint BOOL_VEC3 = 0x8B58;
public const uint BOOL_VEC4 = 0x8B59;
public const uint FLOAT_MAT2 = 0x8B5A;
public const uint FLOAT_MAT3 = 0x8B5B;
public const uint FLOAT_MAT4 = 0x8B5C;
public const uint SAMPLER_2D = 0x8B5E;
public const uint SAMPLER_CUBE = 0x8B60;
public const uint VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
public const uint VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
public const uint VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
public const uint VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
public const uint VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
public const uint VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
public const uint VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
public const uint IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
public const uint IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
public const uint COMPILE_STATUS = 0x8B81;
public const uint LOW_FLOAT = 0x8DF0;
public const uint MEDIUM_FLOAT = 0x8DF1;
public const uint HIGH_FLOAT = 0x8DF2;
public const uint LOW_INT = 0x8DF3;
public const uint MEDIUM_INT = 0x8DF4;
public const uint HIGH_INT = 0x8DF5;
public const uint FRAMEBUFFER = 0x8D40;
public const uint RENDERBUFFER = 0x8D41;
public const uint RGBA4 = 0x8056;
public const uint RGB5_A1 = 0x8057;
public const uint RGB565 = 0x8D62;
public const uint DEPTH_COMPONENT16 = 0x81A5;
public const uint STENCIL_INDEX = 0x1901;
public const uint STENCIL_INDEX8 = 0x8D48;
public const uint DEPTH_STENCIL = 0x84F9;
public const uint RENDERBUFFER_WIDTH = 0x8D42;
public const uint RENDERBUFFER_HEIGHT = 0x8D43;
public const uint RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
public const uint RENDERBUFFER_RED_SIZE = 0x8D50;
public const uint RENDERBUFFER_GREEN_SIZE = 0x8D51;
public const uint RENDERBUFFER_BLUE_SIZE = 0x8D52;
public const uint RENDERBUFFER_ALPHA_SIZE = 0x8D53;
public const uint RENDERBUFFER_DEPTH_SIZE = 0x8D54;
public const uint RENDERBUFFER_STENCIL_SIZE = 0x8D55;
public const uint FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
public const uint FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
public const uint FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
public const uint FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
public const uint COLOR_ATTACHMENT0 = 0x8CE0;
public const uint DEPTH_ATTACHMENT = 0x8D00;
public const uint STENCIL_ATTACHMENT = 0x8D20;
public const uint DEPTH_STENCIL_ATTACHMENT = 0x821A;
public const uint NONE = 0;
public const uint FRAMEBUFFER_COMPLETE = 0x8CD5;
public const uint FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
public const uint FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
public const uint FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
public const uint FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
public const uint FRAMEBUFFER_BINDING = 0x8CA6;
public const uint RENDERBUFFER_BINDING = 0x8CA7;
public const uint MAX_RENDERBUFFER_SIZE = 0x84E8;
public const uint INVALID_FRAMEBUFFER_OPERATION = 0x0506;
public const uint UNPACK_FLIP_Y_WEBGL = 0x9240;
public const uint UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
public const uint CONTEXT_LOST_WEBGL = 0x9242;
public const uint UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
public const uint BROWSER_DEFAULT_WEBGL = 0x9244;
// Desktop OpenGL
public const uint DOUBLE = 0x140A;
// WebGL 2
public const uint READ_BUFFER = 0x0C02;
public const uint UNPACK_ROW_LENGTH = 0x0CF2;
public const uint UNPACK_SKIP_ROWS = 0x0CF3;
public const uint UNPACK_SKIP_PIXELS = 0x0CF4;
public const uint PACK_ROW_LENGTH = 0x0D02;
public const uint PACK_SKIP_ROWS = 0x0D03;
public const uint PACK_SKIP_PIXELS = 0x0D04;
public const uint COLOR = 0x1800;
public const uint DEPTH = 0x1801;
public const uint STENCIL = 0x1802;
public const uint RED = 0x1903;
public const uint RGB8 = 0x8051;
public const uint RGBA8 = 0x8058;
public const uint RGB10_A2 = 0x8059;
public const uint TEXTURE_BINDING_3D = 0x806A;
public const uint UNPACK_SKIP_IMAGES = 0x806D;
public const uint UNPACK_IMAGE_HEIGHT = 0x806E;
public const uint TEXTURE_3D = 0x806F;
public const uint TEXTURE_WRAP_R = 0x8072;
public const uint MAX_3D_TEXTURE_SIZE = 0x8073;
public const uint UNSIGNED_INT_2_10_10_10_REV = 0x8368;
public const uint MAX_ELEMENTS_VERTICES = 0x80E8;
public const uint MAX_ELEMENTS_INDICES = 0x80E9;
public const uint TEXTURE_MIN_LOD = 0x813A;
public const uint TEXTURE_MAX_LOD = 0x813B;
public const uint TEXTURE_BASE_LEVEL = 0x813C;
public const uint TEXTURE_MAX_LEVEL = 0x813D;
public const uint MIN = 0x8007;
public const uint MAX = 0x8008;
public const uint DEPTH_COMPONENT24 = 0x81A6;
public const uint MAX_TEXTURE_LOD_BIAS = 0x84FD;
public const uint TEXTURE_COMPARE_MODE = 0x884C;
public const uint TEXTURE_COMPARE_FUNC = 0x884D;
public const uint CURRENT_QUERY = 0x8865;
public const uint QUERY_RESULT = 0x8866;
public const uint QUERY_RESULT_AVAILABLE = 0x8867;
public const uint STREAM_READ = 0x88E1;
public const uint STREAM_COPY = 0x88E2;
public const uint STATIC_READ = 0x88E5;
public const uint STATIC_COPY = 0x88E6;
public const uint DYNAMIC_READ = 0x88E9;
public const uint DYNAMIC_COPY = 0x88EA;
public const uint MAX_DRAW_BUFFERS = 0x8824;
public const uint DRAW_BUFFER0 = 0x8825;
public const uint DRAW_BUFFER1 = 0x8826;
public const uint DRAW_BUFFER2 = 0x8827;
public const uint DRAW_BUFFER3 = 0x8828;
public const uint DRAW_BUFFER4 = 0x8829;
public const uint DRAW_BUFFER5 = 0x882A;
public const uint DRAW_BUFFER6 = 0x882B;
public const uint DRAW_BUFFER7 = 0x882C;
public const uint DRAW_BUFFER8 = 0x882D;
public const uint DRAW_BUFFER9 = 0x882E;
public const uint DRAW_BUFFER10 = 0x882F;
public const uint DRAW_BUFFER11 = 0x8830;
public const uint DRAW_BUFFER12 = 0x8831;
public const uint DRAW_BUFFER13 = 0x8832;
public const uint DRAW_BUFFER14 = 0x8833;
public const uint DRAW_BUFFER15 = 0x8834;
public const uint MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49;
public const uint MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A;
public const uint SAMPLER_3D = 0x8B5F;
public const uint SAMPLER_2D_SHADOW = 0x8B62;
public const uint FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B;
public const uint PIXEL_PACK_BUFFER = 0x88EB;
public const uint PIXEL_UNPACK_BUFFER = 0x88EC;
public const uint PIXEL_PACK_BUFFER_BINDING = 0x88ED;
public const uint PIXEL_UNPACK_BUFFER_BINDING = 0x88EF;
public const uint FLOAT_MAT2x3 = 0x8B65;
public const uint FLOAT_MAT2x4 = 0x8B66;
public const uint FLOAT_MAT3x2 = 0x8B67;
public const uint FLOAT_MAT3x4 = 0x8B68;
public const uint FLOAT_MAT4x2 = 0x8B69;
public const uint FLOAT_MAT4x3 = 0x8B6A;
public const uint SRGB = 0x8C40;
public const uint SRGB8 = 0x8C41;
public const uint SRGB8_ALPHA8 = 0x8C43;
public const uint COMPARE_REF_TO_TEXTURE = 0x884E;
public const uint RGBA32F = 0x8814;
public const uint RGB32F = 0x8815;
public const uint RGBA16F = 0x881A;
public const uint RGB16F = 0x881B;
public const uint VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD;
public const uint MAX_ARRAY_TEXTURE_LAYERS = 0x88FF;
public const uint MIN_PROGRAM_TEXEL_OFFSET = 0x8904;
public const uint MAX_PROGRAM_TEXEL_OFFSET = 0x8905;
public const uint MAX_VARYING_COMPONENTS = 0x8B4B;
public const uint TEXTURE_2D_ARRAY = 0x8C1A;
public const uint TEXTURE_BINDING_2D_ARRAY = 0x8C1D;
public const uint R11F_G11F_B10F = 0x8C3A;
public const uint UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;
public const uint RGB9_E5 = 0x8C3D;
public const uint UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;
public const uint TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F;
public const uint MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80;
public const uint TRANSFORM_FEEDBACK_VARYINGS = 0x8C83;
public const uint TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84;
public const uint TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85;
public const uint TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88;
public const uint RASTERIZER_DISCARD = 0x8C89;
public const uint MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A;
public const uint MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
public const uint INTERLEAVED_ATTRIBS = 0x8C8C;
public const uint SEPARATE_ATTRIBS = 0x8C8D;
public const uint TRANSFORM_FEEDBACK_BUFFER = 0x8C8E;
public const uint TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F;
public const uint RGBA32UI = 0x8D70;
public const uint RGB32UI = 0x8D71;
public const uint RGBA16UI = 0x8D76;
public const uint RGB16UI = 0x8D77;
public const uint RGBA8UI = 0x8D7C;
public const uint RGB8UI = 0x8D7D;
public const uint RGBA32I = 0x8D82;
public const uint RGB32I = 0x8D83;
public const uint RGBA16I = 0x8D88;
public const uint RGB16I = 0x8D89;
public const uint RGBA8I = 0x8D8E;
public const uint RGB8I = 0x8D8F;
public const uint RED_INTEGER = 0x8D94;
public const uint RGB_INTEGER = 0x8D98;
public const uint RGBA_INTEGER = 0x8D99;
public const uint SAMPLER_2D_ARRAY = 0x8DC1;
public const uint SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;
public const uint SAMPLER_CUBE_SHADOW = 0x8DC5;
public const uint UNSIGNED_INT_VEC2 = 0x8DC6;
public const uint UNSIGNED_INT_VEC3 = 0x8DC7;
public const uint UNSIGNED_INT_VEC4 = 0x8DC8;
public const uint INT_SAMPLER_2D = 0x8DCA;
public const uint INT_SAMPLER_3D = 0x8DCB;
public const uint INT_SAMPLER_CUBE = 0x8DCC;
public const uint INT_SAMPLER_2D_ARRAY = 0x8DCF;
public const uint UNSIGNED_INT_SAMPLER_2D = 0x8DD2;
public const uint UNSIGNED_INT_SAMPLER_3D = 0x8DD3;
public const uint UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;
public const uint UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;
public const uint DEPTH_COMPONENT32F = 0x8CAC;
public const uint DEPTH32F_STENCIL8 = 0x8CAD;
public const uint FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;
public const uint FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210;
public const uint FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211;
public const uint FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212;
public const uint FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213;
public const uint FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214;
public const uint FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215;
public const uint FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216;
public const uint FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217;
public const uint FRAMEBUFFER_DEFAULT = 0x8218;
public const uint UNSIGNED_INT_24_8 = 0x84FA;
public const uint DEPTH24_STENCIL8 = 0x88F0;
public const uint UNSIGNED_NORMALIZED = 0x8C17;
public const uint DRAW_FRAMEBUFFER_BINDING = 0x8CA6; // Same as FRAMEBUFFER_BINDING
public const uint READ_FRAMEBUFFER = 0x8CA8;
public const uint DRAW_FRAMEBUFFER = 0x8CA9;
public const uint READ_FRAMEBUFFER_BINDING = 0x8CAA;
public const uint RENDERBUFFER_SAMPLES = 0x8CAB;
public const uint FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4;
public const uint MAX_COLOR_ATTACHMENTS = 0x8CDF;
public const uint COLOR_ATTACHMENT1 = 0x8CE1;
public const uint COLOR_ATTACHMENT2 = 0x8CE2;
public const uint COLOR_ATTACHMENT3 = 0x8CE3;
public const uint COLOR_ATTACHMENT4 = 0x8CE4;
public const uint COLOR_ATTACHMENT5 = 0x8CE5;
public const uint COLOR_ATTACHMENT6 = 0x8CE6;
public const uint COLOR_ATTACHMENT7 = 0x8CE7;
public const uint COLOR_ATTACHMENT8 = 0x8CE8;
public const uint COLOR_ATTACHMENT9 = 0x8CE9;
public const uint COLOR_ATTACHMENT10 = 0x8CEA;
public const uint COLOR_ATTACHMENT11 = 0x8CEB;
public const uint COLOR_ATTACHMENT12 = 0x8CEC;
public const uint COLOR_ATTACHMENT13 = 0x8CED;
public const uint COLOR_ATTACHMENT14 = 0x8CEE;
public const uint COLOR_ATTACHMENT15 = 0x8CEF;
public const uint FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56;
public const uint MAX_SAMPLES = 0x8D57;
public const uint HALF_FLOAT = 0x140B;
public const uint RG = 0x8227;
public const uint RG_INTEGER = 0x8228;
public const uint R8 = 0x8229;
public const uint RG8 = 0x822B;
public const uint R16F = 0x822D;
public const uint R32F = 0x822E;
public const uint RG16F = 0x822F;
public const uint RG32F = 0x8230;
public const uint R8I = 0x8231;
public const uint R8UI = 0x8232;
public const uint R16I = 0x8233;
public const uint R16UI = 0x8234;
public const uint R32I = 0x8235;
public const uint R32UI = 0x8236;
public const uint RG8I = 0x8237;
public const uint RG8UI = 0x8238;
public const uint RG16I = 0x8239;
public const uint RG16UI = 0x823A;
public const uint RG32I = 0x823B;
public const uint RG32UI = 0x823C;
public const uint VERTEX_ARRAY_BINDING = 0x85B5;
public const uint R8_SNORM = 0x8F94;
public const uint RG8_SNORM = 0x8F95;
public const uint RGB8_SNORM = 0x8F96;
public const uint RGBA8_SNORM = 0x8F97;
public const uint SIGNED_NORMALIZED = 0x8F9C;
public const uint COPY_READ_BUFFER = 0x8F36;
public const uint COPY_WRITE_BUFFER = 0x8F37;
public const uint COPY_READ_BUFFER_BINDING = 0x8F36; // Same as COPY_READ_BUFFER
public const uint COPY_WRITE_BUFFER_BINDING = 0x8F37; // Same as COPY_WRITE_BUFFER
public const uint UNIFORM_BUFFER = 0x8A11;
public const uint UNIFORM_BUFFER_BINDING = 0x8A28;
public const uint UNIFORM_BUFFER_START = 0x8A29;
public const uint UNIFORM_BUFFER_SIZE = 0x8A2A;
public const uint MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B;
public const uint MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D;
public const uint MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E;
public const uint MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F;
public const uint MAX_UNIFORM_BLOCK_SIZE = 0x8A30;
public const uint MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31;
public const uint MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33;
public const uint UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34;
public const uint ACTIVE_UNIFORM_BLOCKS = 0x8A36;
public const uint UNIFORM_TYPE = 0x8A37;
public const uint UNIFORM_SIZE = 0x8A38;
public const uint UNIFORM_BLOCK_INDEX = 0x8A3A;
public const uint UNIFORM_OFFSET = 0x8A3B;
public const uint UNIFORM_ARRAY_STRIDE = 0x8A3C;
public const uint UNIFORM_MATRIX_STRIDE = 0x8A3D;
public const uint UNIFORM_IS_ROW_MAJOR = 0x8A3E;
public const uint UNIFORM_BLOCK_BINDING = 0x8A3F;
public const uint UNIFORM_BLOCK_DATA_SIZE = 0x8A40;
public const uint UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42;
public const uint UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43;
public const uint UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44;
public const uint UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46;
public const uint INVALID_INDEX = 0xFFFFFFFF;
public const uint MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122;
public const uint MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125;
public const uint MAX_SERVER_WAIT_TIMEOUT = 0x9111;
public const uint OBJECT_TYPE = 0x9112;
public const uint SYNC_CONDITION = 0x9113;
public const uint SYNC_STATUS = 0x9114;
public const uint SYNC_FLAGS = 0x9115;
public const uint SYNC_FENCE = 0x9116;
public const uint SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
public const uint UNSIGNALED = 0x9118;
public const uint SIGNALED = 0x9119;
public const uint ALREADY_SIGNALED = 0x911A;
public const uint TIMEOUT_EXPIRED = 0x911B;
public const uint CONDITION_SATISFIED = 0x911C;
public const uint WAIT_FAILED = 0x911D;
public const uint SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
public const uint VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
public const uint ANY_SAMPLES_PASSED = 0x8C2F;
public const uint ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A;
public const uint SAMPLER_BINDING = 0x8919;
public const uint RGB10_A2UI = 0x906F;
public const uint INT_2_10_10_10_REV = 0x8D9F;
public const uint TRANSFORM_FEEDBACK = 0x8E22;
public const uint TRANSFORM_FEEDBACK_PAUSED = 0x8E23;
public const uint TRANSFORM_FEEDBACK_ACTIVE = 0x8E24;
public const uint TRANSFORM_FEEDBACK_BINDING = 0x8E25;
public const uint COMPRESSED_R11_EAC = 0x9270;
public const uint COMPRESSED_SIGNED_R11_EAC = 0x9271;
public const uint COMPRESSED_RG11_EAC = 0x9272;
public const uint COMPRESSED_SIGNED_RG11_EAC = 0x9273;
public const uint COMPRESSED_RGB8_ETC2 = 0x9274;
public const uint COMPRESSED_SRGB8_ETC2 = 0x9275;
public const uint COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
public const uint COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
public const uint COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
public const uint COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
public const uint TEXTURE_IMMUTABLE_FORMAT = 0x912F;
public const uint MAX_ELEMENT_INDEX = 0x8D6B;
public const uint TEXTURE_IMMUTABLE_LEVELS = 0x82DF;
}
}
+33
View File
@@ -56,6 +56,13 @@
<Reference Include="OpenMetaverse">
<HintPath>..\..\opensim-ssh\bin\OpenMetaverse.dll</HintPath>
</Reference>
<Reference Include="OpenMetaverse.Rendering.Meshmerizer">
<HintPath>..\..\opensim-ssh\bin\OpenMetaverse.Rendering.Meshmerizer.dll</HintPath>
</Reference>
<Reference Include="OpenMetaverse.StructuredData, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\opensim-ssh\bin\OpenMetaverse.StructuredData.dll</HintPath>
</Reference>
<Reference Include="OpenMetaverseTypes">
<HintPath>..\..\opensim-ssh\bin\OpenMetaverseTypes.dll</HintPath>
</Reference>
@@ -72,14 +79,26 @@
<Reference Include="OpenSim.Region.Framework">
<HintPath>..\..\opensim-ssh\bin\OpenSim.Region.Framework.dll</HintPath>
</Reference>
<Reference Include="OpenSim.Region.PhysicsModule.BasicPhysics, Version=0.9.1.21260, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\opensim-ssh\bin\OpenSim.Region.PhysicsModule.BasicPhysics.dll</HintPath>
</Reference>
<Reference Include="OpenSim.Region.PhysicsModules.SharedBase, Version=0.9.1.36086, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\opensim-ssh\bin\OpenSim.Region.PhysicsModules.SharedBase.dll</HintPath>
</Reference>
<Reference Include="OpenSim.Services.Interfaces">
<HintPath>..\..\opensim-ssh\bin\OpenSim.Services.Interfaces.dll</HintPath>
</Reference>
<Reference Include="OpenSim.Tests.Common">
<HintPath>..\..\opensim-ssh\bin\OpenSim.Tests.Common.dll</HintPath>
</Reference>
<Reference Include="RSG.Promise">
<HintPath>..\libs\RSG.Promise.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -88,11 +107,25 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BasilAssets.cs" />
<Compile Include="BasilPersist.cs" />
<Compile Include="BasilTerrain.cs" />
<Compile Include="BConverter.cs" />
<Compile Include="BConverterOS.cs" />
<Compile Include="BHasher.cs" />
<Compile Include="Convoar.cs" />
<Compile Include="ConvoarParams.cs" />
<Compile Include="ConvoarStats.cs" />
<Compile Include="EntityGroup.cs" />
<Compile Include="EntityHandle.cs" />
<Compile Include="GltfClasses.cs" />
<Compile Include="Logger.cs" />
<Compile Include="MemAssetService.cs" />
<Compile Include="NullUserAccountService.cs" />
<Compile Include="ParameterParsing.cs" />
<Compile Include="PrimToMesh.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WebGLConstants.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
BIN
View File
Binary file not shown.