I'm new here and also quite new at C#/Unity2019.4.14f with VS2019, MRTK V2.5.3, and Microsoft Hololens 2 programming. I would like to ask you for advice on a problem that I have not been able to solve for weeks. First of all, I would like to quickly explain what kind of problem it is. My task is to track an object that is in an examination cube with the Spatial Mesh and to represent its shape as well as possible.Explanation screen for the task description
The calculations of where the examination cube is located in space work without any problems. But for some reason, I cannot query the Spatial Awareness Mesh Observer. Anyway, no meshes seem to be present although they are visible.
Since I am at a complete loss and no one I have asked so far has been able to help me, I am publishing my code for this function below. Please bear with me, as I am still a beginner in writing code.
public void ReadAndDrawMesh(){
//Provide a list of the cube coordinates
Vector3[] CubeCoordinateList = new Vector3[24];
//Convert Local to World Coordinates
var localToWorld = transform.localToWorldMatrix;
Vector3 cubeWorldPos = Cube.transform.position; // Reading out the centre position
Vector3[] cubeVertices = Cube.GetComponent<MeshFilter>().mesh.vertices; //World coordinates?
List<Vector3> cubeWorldVertices = new List<Vector3>();
for (int i = 0; i <= (cubeVertices.Length) - 1; i++)
{
CubeCoordinateList[i] = localToWorld.MultiplyPoint3x4(cubeVertices[i]);
}
//CubeVerticies from Vector A[0] to E[4]
float normalX1 = CubeCoordinateList[4].x - CubeCoordinateList[0].x;
float normalY1 = CubeCoordinateList[4].y - CubeCoordinateList[0].y;
float normalZ1 = CubeCoordinateList[4].z - CubeCoordinateList[0].z;
float amount1 = Mathf.Sqrt((normalX1 * normalX1) + (normalY1 * normalY1) + (normalZ1 * normalZ1));
//Create a new vector
Vector3 direction1 = new Vector3(normalX1, normalY1, normalZ1);
direction1 = direction1 / amount1;
//CubeVerticies from Vector A[0] to B[2]
float normalX2 = CubeCoordinateList[2].x - CubeCoordinateList[0].x;
float normalY2 = CubeCoordinateList[2].y - CubeCoordinateList[0].y;
float normalZ2 = CubeCoordinateList[2].z - CubeCoordinateList[0].z;
float amount2 = Mathf.Sqrt((normalX2 * normalX2) + (normalY2 * normalY2) + (normalZ2 * normalZ2));
//Create a new vector
Vector3 direction2 = new Vector3(normalX2, normalY2, normalZ2);
direction2 = direction2 / amount2;
//CubeVerticies from Vector A[0] to D[3]
float normalX3 = CubeCoordinateList[3].x - CubeCoordinateList[0].x;
float normalY3 = CubeCoordinateList[3].y - CubeCoordinateList[0].y;
float normalZ3 = CubeCoordinateList[3].z - CubeCoordinateList[0].z;
float amount3 = Mathf.Sqrt((normalX3 * normalX3) + (normalY3 * normalY3) + (normalZ3 * normalZ3));
//Create a new vector
Vector3 direction3 = new Vector3(normalX3, normalY3, normalZ3);
direction3 = direction3 / amount3;
//From MRTK 2.5.3
// Use CoreServices to quickly get access to the IMixedRealitySpatialAwarenessSystem
var spatialAwarenessService = CoreServices.SpatialAwarenessSystem;
// Cast to the IMixedRealityDataProviderAccess to get access to the data providers
var dataProviderAccess = spatialAwarenessService as IMixedRealityDataProviderAccess;
var meshObserverName = "SpatialAwarenessMeshObserverProfile";
var MeshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);
foreach (SpatialAwarenessMeshObject meshObject in MeshObserver.Meshes.Values)
{
Vector3[] meshObjectarray = meshObject.Filter.mesh.vertices;
//Reading the Spatial Mesh of the room
foreach (Vector3 verticiesCoordinaten in meshObjectarray)
{
//List for the mesh coordinates that come out of the scalar product calculation
Vector3[] MeshPositionList = new Vector3[meshObjectarray.Length]; ;
//Determining Direction between verticiesCoordinates of MeshObject with Centre of Cube
var dir_vectorMesh = verticiesCoordinaten - cubeWorldPos;
//Calculating the scalar product of the coordinates
var result1 = Mathf.Abs(Vector3.Dot(dir_vectorMesh, direction1)) * 2;
var result2 = Mathf.Abs(Vector3.Dot(dir_vectorMesh, direction2)) * 2;
var result3 = Mathf.Abs(Vector3.Dot(dir_vectorMesh, direction3)) * 2;
// If scalar product Negative, then write it in the list
if (result1 > amount1 && result2 > amount2 && result3 > amount3)
{
MeshPositionList[meshObjectarray.Length] = verticiesCoordinaten;
}
//Creating a new visible mesh from the points in the list
Mesh mesh = new Mesh();
mesh.vertices = MeshPositionList;
mesh.Optimize();
Graphics.DrawMeshNow(mesh, Vector3.zero, Quaternion.identity);
mesh.RecalculateNormals();
}
}
}
I hope that one of you can help me and I look forward to any constructive answers. Thank you to everyone who reads this post and perhaps responds.
Thank You.
I make a scene with parallax effect. I can’t make the sprite move smoothly along the X axis. The problem is that regardless of whether I use SDL_RenderCopyF or SDL_RenderCopy, the sprite is drawn according to the pixel grid of the monitor when moving slowly, which is accompanied by a jitter effect,
when there are many layers and everyone moves at different speeds.
My problem is like SDL2 Smooth texture(sprite) animation between points in time function
But there was a version of SDL2 that did not support floating-point rendering, and the author had to patch it. Starting from version 2.0.10.0, SDL_RenderCopyF, SDL_FRect and other functions have been added to the SDL, with which you can implement subpixel moving sprites, but I can not get them to work in my scene.
There are 10 layers in FullHD resolution. Rendering occurs in the FullHD window.
Window and render initialization code:
void CreateWidnow()
{
var windowFlags = Settings.Fullscreen ?
SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN : Settings.Resizeble ?
SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE : SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN;
renderWindow = SDL.SDL_CreateWindow(
Settings.DebugMode ? $"{Settings.Title} [DEBUG]" : Settings.Title, SDL.SDL_WINDOWPOS_CENTERED,
SDL.SDL_WINDOWPOS_CENTERED,
Settings.Resolution.Width,
Settings.Resolution.Height,
windowFlags);
}
void CreateRenderer()
{
if(Settings.VSinc) {
renderer = SDL.SDL_CreateRenderer(
renderWindow, -1,
SDL.SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC |
SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED |
SDL.SDL_RendererFlags.SDL_RENDERER_TARGETTEXTURE
);
}
else
{
renderer = SDL.SDL_CreateRenderer(
renderWindow, -1,
SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED |
SDL.SDL_RendererFlags.SDL_RENDERER_TARGETTEXTURE
);
}
}
The main cycle with the calculation of deltaTime:
void RenderLoop()
{
bool cap = Settings.FPS > 0;
var timer_fps = new Timer();
ulong now_counter = SDL.SDL_GetPerformanceCounter();
ulong last_counter = 0;
double deltaTime = 0;
while (renderLoop)
{
timer_fps.Start();
last_counter = now_counter;
now_counter = SDL.SDL_GetPerformanceCounter();
deltaTime = (double)(now_counter - last_counter) / SDL.SDL_GetPerformanceFrequency();
OnPreUpdate(deltaTime);
OnUpdate(deltaTime);
SDL.SDL_RenderPresent(renderer);
OnPostUpdate(deltaTime);
if( ( cap ) && ( timer_fps.GetTicks() < 1000 / Settings.FPS ) )
{
SDL.SDL_Delay( ( 1000 / Settings.FPS ) - timer_fps.GetTicks() );
}
}
}
Sprite loading and rendering code:
public Sprite(string path)
{
Path = path;
Transform = new Transform(new Point(0, 0));
sprite = Image.IMG_LoadTexture(Game.RenderContext, path);
SDL.SDL_QueryTexture(sprite, out format, out access, out width, out height); // get the width and height of the texture
draw_rect = new SDL.SDL_FRect();
draw_rect.w = width;
draw_rect.h = height;
scr_rect.x = 0; scr_rect.y = 0; scr_rect.w = width; scr_rect.h = height;
}
public Transform Transform
{
get; set;
}
public void Draw()
{
draw_rect.x = (float)Transform.Position.X;
draw_rect.y = (float)Transform.Position.Y;
SDL.SDL_RenderCopyExF(Game.RenderContext, sprite, ref scr_rect, ref draw_rect, Transform.Degrees, IntPtr.Zero, SDL.SDL_RendererFlip.SDL_FLIP_NONE);
}
Moving Function (Transform.Translate):
public void Translate(double x, double y)
{
position.X += x;
position.Y += y;
}
Parallax implementation function (move the sprites back to the right side when they leave the screen):
void layerDraw(Sprite l1, Sprite l2, double speed)
{
l1.Transform.Translate(speed, 0);
l1.Draw();
l2.Transform.Translate(speed, 0);
l2.Draw();
if (l1.Transform.Position.X <= -Settings.Resolution.Width)
l1.Transform.SetPosition(Settings.Resolution.Width + l2.Transform.Position.X, 0);
if (l2.Transform.Position.X <= -Settings.Resolution.Width)
l2.Transform.SetPosition(Settings.Resolution.Width + l1.Transform.Position.X, 0);
}
Parallax Rendering Function:
double speed_09 = -2.0, speed_08 = -4.0, speed_07 = -8.0, speed_06 = -16.0;
double speed_05 = -24.0, speed_04 = -32.0, speed_03 = -64.0, speed_02 = -96.0, speed_01 = -128.0;
protected override void Update(double deltaTime)
{
background.Draw();
layerDraw(forest_091, forest_092, speed_09 * deltaTime);
layerDraw(forest_081, forest_082, speed_08 * deltaTime);
layerDraw(forest_071, forest_072, speed_07 * deltaTime);
layerDraw(forest_061, forest_062, speed_06 * deltaTime);
layerDraw(particles051, particles052, speed_05 * deltaTime);
layerDraw(forest_041, forest_042, speed_04 * deltaTime);
layerDraw(particles_031, particles_032, speed_03 * deltaTime);
layerDraw(bushes_021, bushes_022, speed_02 * deltaTime);
layerDraw(mist_011, mist_012, speed_01 * deltaTime);
}
Outputting forest_091 coordinates to the console:
[11:31:07:32] (x,y): = (1902,7461329999965:0), deltaTime = 0,001391, speed = -0,002782
[11:31:07:32] (x:y): = (1902,7430913999965:0), deltaTime = 0,0015208, speed = -0,0030416
[11:31:07:32] (x:y): = (1902,7400399999965:0), deltaTime = 0,0015257, speed = -0,0030514
[11:31:07:32] (x:y): = (1902,7370409999965:0), deltaTime = 0,0014995, speed = -0,002999
[11:31:07:32] (x:y): = (1902,7339605999964:0), deltaTime = 0,0015402, speed = -0,0030804
[11:31:07:33] (x:y): = (1902,7300727999964:0), deltaTime = 0,0019439, speed = -0,0038878
[11:31:07:33] (x:y): = (1902,7271281999963:0), deltaTime = 0,0014723, speed = -0,0029446
[11:31:07:33] (x:y): = (1902,7241953999962:0), deltaTime = 0,0014664, speed = -0,0029328
[11:31:07:33] (x:y): = (1902,7212207999962:0), deltaTime = 0,0014873, speed = -0,0029746
[11:31:07:33] (x:y): = (1902,7181395999962:0), deltaTime = 0,0015406, speed = -0,0030812
[11:31:07:33] (x:y): = (1902,715346599996:0), deltaTime = 0,0013965, speed = -0,002793
[11:31:07:33] (x:y): = (1902,712221399996:0), deltaTime = 0,0015626, speed = -0,0031252
[11:31:07:34] (x:y): = (1902,709382799996:0), deltaTime = 0,0014193, speed = -0,0028386
Link to youtube with a demonstration of the problemы
I use nectcore3.1, SDL2-CS и SDL2 v2.0.10.0
UPD: log deltaTime calculations:
[08:48:34:25] now_counter = 1097310517365, last_counter = 1097310516099, now_counter-last_counter = 1266
[08:48:34:25] now_counter = 1097310519141, last_counter = 1097310517365, now_counter-last_counter = 1776
[08:48:34:25] now_counter = 1097310521406, last_counter = 1097310519141, now_counter-last_counter = 2265
[08:48:34:25] now_counter = 1097310532746, last_counter = 1097310521406, now_counter-last_counter = 11340
[08:48:34:25] now_counter = 1097310534069, last_counter = 1097310532746, now_counter-last_counter = 1323
[08:48:34:25] now_counter = 1097310535356, last_counter = 1097310534069, now_counter-last_counter = 1287
[08:48:34:25] now_counter = 1097310536628, last_counter = 1097310535356, now_counter-last_counter = 1272
[08:48:34:25] now_counter = 1097310537897, last_counter = 1097310536628, now_counter-last_counter = 1269
[08:48:34:25] now_counter = 1097310539169, last_counter = 1097310537897, now_counter-last_counter = 1272
[08:48:34:25] now_counter = 1097310540441, last_counter = 1097310539169, now_counter-last_counter = 1272`
Thanks to keltar for the answers and the time spent. In fact, I struggled for a long time to solve this problem and sincerely did not understand why even after adding the ability to draw floating-point sprites in SDL2, they still drew me according to the pixel grid of the monitor.
The good news: deltaTime is calculated correctly,
And there are no problems with rounding double when transferring coordinates to the SDL render!
Bad news: the solution is too simple to spend a few days on it.
SDL.SDL_SetHint (SDL.SDL_HINT_RENDER_SCALE_QUALITY, "2");
This line tells SDL2 to use Anisatropic filtering when rendering sprites.
It made my animation flow smoothly.
Before 5.5 particle system variables could be accessed via ParticleSystem and were read/write. Now they're accessed via ParticleSystem.MainModule and thus a lot of code has become obsolete. The API Updater has not been able to fix most of the issues. I've read through the new documentation but I can't figure out how the new variable types are supposed to be used. For example in JetParticleEffect.cs this line causes a warning:
// set the original properties from the particle system
m_OriginalLifetime = m_System.startLifetime;
The warning states: 'ParticleSystem.startLifetime' is obsolete: 'startLifetime property is deprecated. Use main.startLifetime or main.startLifetimeMultiplier instead.'
I've tried the following:
m_OriginalLifetime = m_System.main.startLifetime;
// error: Cannot implicitly convert type 'UnityEngine.ParticleSystem.MinMaxCurve' to 'float'
I believe the answer has something to do with the minMaxCurve constant variables as this compiles:
m_OriginalLifetime = m_System.main.startLifetime.constant;
But there is almost no explaination in the docs. Can anyone shed some light on this?
Also, where do the new multipliers fit in? I assume where previously you could do this:
particle.startSize *= myMultiplier
... you should now do this?
particle.main.startSizeMultiplier = myMultiplier
particle.startLifetime:
First of all, what Unity did in Unity 5.5 was to add new futures to the ParticleSystem. They also exposed some ParticleSystem API that was hidden before.
ParticleSystem.MainModule.startLifetime is now a type of MinMaxCurve instead of float like ParticleSystem.startLifetime.
By doing this, you are now given more options such as modifying the startLifetime as a curve.
Reading or writing to ParticleSystem.MainModule.startLifetime depends on the value of ParticleSystem.MainModule.startLifetime.mode which is set through the Editor or via code.
The default value of ParticleSystem.MainModule.startLifetime.mode is ParticleSystemCurveMode.Constant
So your m_OriginalLifetime = m_System.main.startLifetime.constant; is fine.
If startLifetime is dynamically or randomly changed to another mode during run-time, then you will have to do something like this:
ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;
ParticleSystem.MinMaxCurve minMaxCurve = main.startLifetime;
if (minMaxCurve.mode == ParticleSystemCurveMode.Constant)
{
m_OriginalLifetime = m_System.main.startLifetime.constant;
}
else if (minMaxCurve.mode == ParticleSystemCurveMode.Curve)
{
AnimationCurve animCurveLifetime = m_System.main.startLifetime.curve;
}
...
particle.startSize:
The-same thing apply to particle.startSize.
The particle.startSize property is now m_System.main.startSize;
Although you can't do m_System.main.startSize.constant *= myMultiplier; because your old code was particle.startSize *= myMultiplier.
You need to get m_System.main.startSize, modify it then assign the modified m_System.main.startSize back to m_System.main.startSize.
particle.startSize *= myMultiplier should be:
ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;
ParticleSystem.MinMaxCurve minMaxCurve = main.startSize; //Get Size
minMaxCurve.constant *= myMultiplier; //Modify Size
main.startSize = minMaxCurve; //Assign the modified startSize back
Then, what are particle.main.startSizeMultiplier and particle.main.startSize used for?
This two variables can also be used to change startLifetime and startSize. It's main advantage is that it is very efficient. It does not not require that you make a copy of MinMaxCurve like we did above, in order to change startSize or startSizeMultiplier.
ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;
main.startSizeMultiplier = 5;
and
ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;
main.startLifetimeMultiplier = 8;
Use them if your ParticleSystem.MainModule.startLifetime.mode is constant. This will to change the overall lifetime multiplier or the the overall size multiplier efficiently.
Changing Color and Color Modes
Color:
There is an implicit operator that lets you use:
ParticleSystem.MainModule main = trailPartical.main;
main.startColor = Color.red;
but startColor is not actually type of Color. The startColor variable is now a type of ParticleSystem.MinMaxGradient.
This is how you should be changing the particle startColor:
//Create Color
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.Color;
color.color = Color.red;
//Assign the color to your particle
ParticleSystem.MainModule main = trailPartical.main;
main.startColor = color;
Gradient:
public ParticleSystem particleSystem;
void Start()
{
//Create Gradient key
GradientColorKey[] gradientColorKey;
gradientColorKey = new GradientColorKey[3];
gradientColorKey[0].color = Color.red;
gradientColorKey[0].time = 0f;
gradientColorKey[1].color = Color.blue;
gradientColorKey[1].time = 0.5f;
gradientColorKey[2].color = Color.green;
gradientColorKey[2].time = 1f;
//Create Gradient alpha
GradientAlphaKey[] gradientAlphaKey;
gradientAlphaKey = new GradientAlphaKey[3];
gradientAlphaKey[0].alpha = 1.0f;
gradientAlphaKey[0].time = 0.0f;
gradientAlphaKey[1].alpha = 0.5f;
gradientAlphaKey[1].time = 0.5f;
gradientAlphaKey[2].alpha = 1f;
gradientAlphaKey[2].time = 1f;
//Create Gradient
Gradient gradient = new Gradient();
gradient.SetKeys(gradientColorKey, gradientAlphaKey);
//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.Gradient;
color.gradient = gradient;
//Assign the color to particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
}
Random Between Two Colors:
//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.TwoColors;
color.colorMin = Color.red;
color.colorMax = Color.green;
//Assign the color to the particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
Random Between Two Gradients:
public ParticleSystem particleSystem;
void Start()
{
//Create Gradient key Min
GradientColorKey[] gradientColorKeyMin;
gradientColorKeyMin = new GradientColorKey[3];
gradientColorKeyMin[0].color = Color.red;
gradientColorKeyMin[0].time = 0f;
gradientColorKeyMin[1].color = Color.blue;
gradientColorKeyMin[1].time = 0.5f;
gradientColorKeyMin[2].color = Color.green;
gradientColorKeyMin[2].time = 1f;
//Create Gradient alpha Min
GradientAlphaKey[] gradientAlphaKeyMin;
gradientAlphaKeyMin = new GradientAlphaKey[3];
gradientAlphaKeyMin[0].alpha = 1.0f;
gradientAlphaKeyMin[0].time = 0.0f;
gradientAlphaKeyMin[1].alpha = 0.5f;
gradientAlphaKeyMin[1].time = 0.5f;
gradientAlphaKeyMin[2].alpha = 1f;
gradientAlphaKeyMin[2].time = 1f;
//Create Gradient key Max
GradientColorKey[] gradientColorKeyMax;
gradientColorKeyMax = new GradientColorKey[3];
gradientColorKeyMax[0].color = Color.red;
gradientColorKeyMax[0].time = 0f;
gradientColorKeyMax[1].color = Color.blue;
gradientColorKeyMax[1].time = 0.5f;
gradientColorKeyMax[2].color = Color.green;
gradientColorKeyMax[2].time = 1f;
//Create Gradient alpha Max
GradientAlphaKey[] gradientAlphaKeyMax;
gradientAlphaKeyMax = new GradientAlphaKey[3];
gradientAlphaKeyMax[0].alpha = 1.0f;
gradientAlphaKeyMax[0].time = 0.0f;
gradientAlphaKeyMax[1].alpha = 0.5f;
gradientAlphaKeyMax[1].time = 0.5f;
gradientAlphaKeyMax[2].alpha = 1f;
gradientAlphaKeyMax[2].time = 1f;
//Create Gradient Min
Gradient gradientMin = new Gradient();
gradientMin.SetKeys(gradientColorKeyMin, gradientAlphaKeyMin);
//Create Gradient Max
Gradient gradientMax = new Gradient();
gradientMax.SetKeys(gradientColorKeyMax, gradientAlphaKeyMax);
//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.TwoGradients;
color.gradientMin = gradientMin;
color.gradientMax = gradientMax;
//Assign the color to the particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
}
Random Color:
public ParticleSystem particleSystem;
void Start()
{
//Create Gradient key Min
GradientColorKey[] gradientColorKeyMin;
gradientColorKeyMin = new GradientColorKey[3];
gradientColorKeyMin[0].color = Color.red;
gradientColorKeyMin[0].time = 0f;
gradientColorKeyMin[1].color = Color.blue;
gradientColorKeyMin[1].time = 0.5f;
gradientColorKeyMin[2].color = Color.green;
gradientColorKeyMin[2].time = 1f;
//Create Gradient alpha Min
GradientAlphaKey[] gradientAlphaKeyMin;
gradientAlphaKeyMin = new GradientAlphaKey[3];
gradientAlphaKeyMin[0].alpha = 1.0f;
gradientAlphaKeyMin[0].time = 0.0f;
gradientAlphaKeyMin[1].alpha = 0.5f;
gradientAlphaKeyMin[1].time = 0.5f;
gradientAlphaKeyMin[2].alpha = 1f;
gradientAlphaKeyMin[2].time = 1f;
//Create Gradient key Max
GradientColorKey[] gradientColorKeyMax;
gradientColorKeyMax = new GradientColorKey[3];
gradientColorKeyMax[0].color = Color.red;
gradientColorKeyMax[0].time = 0f;
gradientColorKeyMax[1].color = Color.blue;
gradientColorKeyMax[1].time = 0.5f;
gradientColorKeyMax[2].color = Color.green;
gradientColorKeyMax[2].time = 1f;
//Create Gradient alpha Max
GradientAlphaKey[] gradientAlphaKeyMax;
gradientAlphaKeyMax = new GradientAlphaKey[3];
gradientAlphaKeyMax[0].alpha = 1.0f;
gradientAlphaKeyMax[0].time = 0.0f;
gradientAlphaKeyMax[1].alpha = 0.5f;
gradientAlphaKeyMax[1].time = 0.5f;
gradientAlphaKeyMax[2].alpha = 1f;
gradientAlphaKeyMax[2].time = 1f;
//Create Gradient Min
Gradient gradientMin = new Gradient();
gradientMin.SetKeys(gradientColorKeyMin, gradientAlphaKeyMin);
//Create Gradient Max
Gradient gradientMax = new Gradient();
gradientMax.SetKeys(gradientColorKeyMax, gradientAlphaKeyMax);
//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.RandomColor;
color.gradientMin = gradientMin;
color.gradientMax = gradientMax;
//Assign the color to the particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
}
so I'm currently working on resolution independence for my game, and I'm testing it out on a sword image. The position changing is working, but whenever I start doing the size I end up with a blank screen.
These are the functions I run to get the new position and size of the sprite.
private static float CalcRatio(Vector2 size)
{
return size.Y / size.X;
}
public static Vector2 CalculateNewPos(Vector2 refPos, Vector2 refScreenSize, Vector2 currentScreenSize)
{
return new Vector2((refPos.X / refScreenSize.X) * currentScreenSize.X,
(refPos.Y / refScreenSize.Y) * currentScreenSize.Y);
}
public static Vector2 CalculateNewSize(Vector2 refSize, Vector2 refScreenSize, Vector2 currenScreenSize)
{
float origRatio = CalcRatio(refSize);
float perW = refSize.X * 100f / refScreenSize.X;
float newW = perW / 100f * currenScreenSize.X;
float newH = newW * origRatio;
return new Vector2(newW, newH);
}
In the Initialization function in Game1 I run this code:
graphics.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
graphics.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
swordPosition = CalculateNewPos(swordRefPosition, new Vector2(1920, 1080), new Vector2(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width, GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height));
swordSize = CalculateNewSize(swordRefSize, new Vector2(1920, 1080), new Vector2(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width, GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height));
In the load function I run this:
swordTexture = content.Load<Texture2D>("SOLDIER_Sword");
swordPosition = new Vector2(300, 0);
swordRefSize = new Vector2(557, 490);
swordSize = new Vector2(557, 490);
swordRefPosition = new Vector2(300, 0);
swordColor = Color.White;
sword = new StaticSprite(swordTexture, swordPosition, swordSize, swordColor);
In update everytime the screen resolution changes (I have buttons set to do that) this:
graphics.PreferredBackBufferHeight = setHeight;
graphics.PreferredBackBufferWidth = setWidth;
graphics.ApplyChanges();
swordPosition = CalculateNewPos(swordRefPosition, new Vector2(1920, 1080), new Vector2(setWidth, setHeight));
swordSize = CalculateNewSize(swordRefSize, new Vector2(1920, 1080), new Vector2(setWidth, setHeight));
And in draw:
batch.Draw(swordTexture, swordPosition, null, swordColor, 0f, Vector2.Zero, swordSize, SpriteEffects.None, 0f);
Sorry there is so much code, I'm really stumped and can't pinpoint where it's going wrong, so I just included everything that changes the variables.
Thank you so much for taking the time to look through this.
Note that current display mode is only meaningful if you are fullscreen. It's the VIEWPORT that tells you the width/height of spritebatch's projection matrix.
That said, you should really look into Bjarke's post, because you don't usually want to be rescaling every individual item.
UIImageView not show/display Original Image as that of available on server.
for more ref check it
float scaleFactor = 0.0f;`
float scaleWidth = dstRectangle.Width; //width =748
float scaleHeight = dstRectangle.Height; // height = 759
if(!SizeF.Equals(srcRectangle ,dstRectangle))
{
float widthFactor =(float) dstRectangle.Width / srcRectangle.Width; //srcRectHeight = 512
float heightFactor =(float) dstRectangle.Height / srcRectangle.Height; //srcRectangle.Height = 314
if(widthFactor >heightFactor)
scaleFactor = widthFactor ;
else
scaleFactor = heightFactor;
scaleWidth = srcRectangle.Width * scaleFactor;
scaleHeight = srcRectangle.Height * scaleFactor;
if(widthFactor >heightFactor)
{
thumbnailPoint.Y = (dstRectangle.Height - scaleHeight) * .5f;
}
else
if(widthFactor < heightFactor)
{
thumbnailPoint.X = (dstRectangle.Width - scaleWidth) *.5f;
}
}
UIGraphics.BeginImageContext(new SizeF(dstRectangle.Width , dstRectangle.Height));
RectangleF thumbnailRect = RectangleF.Empty;
thumbnailRect.Offset(thumbnailPoint);
thumbnailRect.Size.Width = scaleWidth;
thumbnailRect.Size.Height = scaleHeight;
CGImage _bitmap = UIGraphics.GetImageFromCurrentImageContext().CGImage;
ImgVIew.Image = UIImage.FromImage(_bitmap);
UIGraphics.EndImageContext();
It gives me an UIImage But not display on the UIImageView
In CGImage I got ALphaInfo = PremultipledLast
BitsPerComponant = 8
BitsPerPixel =32
BytesPerRow = 3008
Height= 759
Width = 748
this values I get into CGImage but this CGImage I conver it to UIImage but still it can not display
Can you just do something like this:
using (var url = NSUrl.FromString ("http://yoururl.com/yourpic.jpg"))
{
using (var data = NSData.FromUrl (url))
{
imageView.Image = UIImage.LoadFromData (data);
}
}
It sounds like you just need to download an image and set it to a UIImageView, right?
It seems like you are writing a lot of code for something pretty simple.
NOTE: use a try-catch for networking errors.